@lvce-editor/main-area-worker 6.7.0 → 7.1.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 +330 -214
- package/package.json +2 -2
|
@@ -93,6 +93,7 @@ const Span = 8;
|
|
|
93
93
|
const Text = 12;
|
|
94
94
|
const Img = 17;
|
|
95
95
|
const Pre = 51;
|
|
96
|
+
const Reference = 100;
|
|
96
97
|
|
|
97
98
|
const Button = 'event.button';
|
|
98
99
|
const ClientX = 'event.clientX';
|
|
@@ -215,6 +216,12 @@ const number = value => {
|
|
|
215
216
|
throw new AssertionError('expected value to be of type number');
|
|
216
217
|
}
|
|
217
218
|
};
|
|
219
|
+
const string = value => {
|
|
220
|
+
const type = getType(value);
|
|
221
|
+
if (type !== String$1) {
|
|
222
|
+
throw new AssertionError('expected value to be of type string');
|
|
223
|
+
}
|
|
224
|
+
};
|
|
218
225
|
|
|
219
226
|
const isMessagePort = value => {
|
|
220
227
|
return value && value instanceof MessagePort;
|
|
@@ -1666,12 +1673,64 @@ const closeFocusedTab = state => {
|
|
|
1666
1673
|
return closeTab(state, focusedGroup.id, activeTabId);
|
|
1667
1674
|
};
|
|
1668
1675
|
|
|
1676
|
+
const closeOtherTabs = (state, groupId) => {
|
|
1677
|
+
const {
|
|
1678
|
+
layout
|
|
1679
|
+
} = state;
|
|
1680
|
+
const {
|
|
1681
|
+
groups
|
|
1682
|
+
} = layout;
|
|
1683
|
+
const group = groups.find(g => g.id === groupId);
|
|
1684
|
+
if (!group) {
|
|
1685
|
+
return state;
|
|
1686
|
+
}
|
|
1687
|
+
const {
|
|
1688
|
+
activeTabId
|
|
1689
|
+
} = group;
|
|
1690
|
+
if (activeTabId === undefined) {
|
|
1691
|
+
return state;
|
|
1692
|
+
}
|
|
1693
|
+
const newGroups = groups.map(g => {
|
|
1694
|
+
if (g.id === groupId) {
|
|
1695
|
+
const newTabs = g.tabs.filter(tab => tab.id === activeTabId);
|
|
1696
|
+
return {
|
|
1697
|
+
...g,
|
|
1698
|
+
activeTabId,
|
|
1699
|
+
isEmpty: newTabs.length === 0,
|
|
1700
|
+
tabs: newTabs
|
|
1701
|
+
};
|
|
1702
|
+
}
|
|
1703
|
+
return g;
|
|
1704
|
+
});
|
|
1705
|
+
return {
|
|
1706
|
+
...state,
|
|
1707
|
+
layout: {
|
|
1708
|
+
...layout,
|
|
1709
|
+
groups: newGroups
|
|
1710
|
+
}
|
|
1711
|
+
};
|
|
1712
|
+
};
|
|
1713
|
+
|
|
1714
|
+
const copyPath$1 = async (state, path) => {
|
|
1715
|
+
string(path);
|
|
1716
|
+
await invoke('ClipBoard.writeText', path);
|
|
1717
|
+
return state;
|
|
1718
|
+
};
|
|
1719
|
+
|
|
1720
|
+
const copyRelativePath$1 = async (state, path) => {
|
|
1721
|
+
string(path);
|
|
1722
|
+
const relativePath = await invoke('Workspace.pathBaseName', path);
|
|
1723
|
+
await invoke('ClipBoard.writeText', relativePath);
|
|
1724
|
+
return state;
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1669
1727
|
const create = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
|
|
1670
1728
|
const state = {
|
|
1671
1729
|
assetDir,
|
|
1672
1730
|
fileIconCache: {},
|
|
1673
1731
|
height,
|
|
1674
1732
|
iframes: [],
|
|
1733
|
+
initial: true,
|
|
1675
1734
|
layout: {
|
|
1676
1735
|
activeGroupId: undefined,
|
|
1677
1736
|
direction: 'horizontal',
|
|
@@ -1696,7 +1755,7 @@ const RenderItems = 4;
|
|
|
1696
1755
|
const RenderIncremental = 11;
|
|
1697
1756
|
|
|
1698
1757
|
const modules = [isEqual];
|
|
1699
|
-
const numbers = [
|
|
1758
|
+
const numbers = [RenderIncremental];
|
|
1700
1759
|
|
|
1701
1760
|
const diff = (oldState, newState) => {
|
|
1702
1761
|
const diffResult = [];
|
|
@@ -2162,6 +2221,222 @@ const handleDoubleClick = async state => {
|
|
|
2162
2221
|
return state;
|
|
2163
2222
|
};
|
|
2164
2223
|
|
|
2224
|
+
const MainTabs = 'MainTabs';
|
|
2225
|
+
|
|
2226
|
+
const getBasename$1 = uri => {
|
|
2227
|
+
const lastSlashIndex = uri.lastIndexOf('/');
|
|
2228
|
+
if (lastSlashIndex === -1) {
|
|
2229
|
+
return uri;
|
|
2230
|
+
}
|
|
2231
|
+
return uri.slice(lastSlashIndex + 1);
|
|
2232
|
+
};
|
|
2233
|
+
const getLabel = uri => {
|
|
2234
|
+
if (uri.startsWith('settings://')) {
|
|
2235
|
+
return 'Settings';
|
|
2236
|
+
}
|
|
2237
|
+
if (uri.startsWith('simple-browser://')) {
|
|
2238
|
+
return 'Simple Browser';
|
|
2239
|
+
}
|
|
2240
|
+
return getBasename$1(uri);
|
|
2241
|
+
};
|
|
2242
|
+
|
|
2243
|
+
const createEmptyGroup = (state, uri, requestId) => {
|
|
2244
|
+
const {
|
|
2245
|
+
layout
|
|
2246
|
+
} = state;
|
|
2247
|
+
const {
|
|
2248
|
+
groups
|
|
2249
|
+
} = layout;
|
|
2250
|
+
const groupId = create$1();
|
|
2251
|
+
const title = getLabel(uri);
|
|
2252
|
+
const tabId = create$1();
|
|
2253
|
+
const editorUid = create$1();
|
|
2254
|
+
const newTab = {
|
|
2255
|
+
editorType: 'text',
|
|
2256
|
+
editorUid,
|
|
2257
|
+
errorMessage: '',
|
|
2258
|
+
icon: '',
|
|
2259
|
+
id: tabId,
|
|
2260
|
+
isDirty: false,
|
|
2261
|
+
language: '',
|
|
2262
|
+
loadingState: 'loading',
|
|
2263
|
+
title,
|
|
2264
|
+
uri
|
|
2265
|
+
};
|
|
2266
|
+
const newGroup = {
|
|
2267
|
+
activeTabId: newTab.id,
|
|
2268
|
+
focused: true,
|
|
2269
|
+
id: groupId,
|
|
2270
|
+
isEmpty: false,
|
|
2271
|
+
size: 100,
|
|
2272
|
+
tabs: [newTab]
|
|
2273
|
+
};
|
|
2274
|
+
return {
|
|
2275
|
+
...state,
|
|
2276
|
+
layout: {
|
|
2277
|
+
...layout,
|
|
2278
|
+
activeGroupId: groupId,
|
|
2279
|
+
groups: [...groups, newGroup]
|
|
2280
|
+
}
|
|
2281
|
+
};
|
|
2282
|
+
};
|
|
2283
|
+
|
|
2284
|
+
const getActiveTabId = state => {
|
|
2285
|
+
const {
|
|
2286
|
+
layout
|
|
2287
|
+
} = state;
|
|
2288
|
+
const {
|
|
2289
|
+
activeGroupId,
|
|
2290
|
+
groups
|
|
2291
|
+
} = layout;
|
|
2292
|
+
const activeGroup = groups.find(g => g.id === activeGroupId);
|
|
2293
|
+
return activeGroup?.activeTabId;
|
|
2294
|
+
};
|
|
2295
|
+
|
|
2296
|
+
const openTab = (state, groupId, tab) => {
|
|
2297
|
+
const newTab = 'id' in tab && tab.id !== undefined ? tab : {
|
|
2298
|
+
...tab,
|
|
2299
|
+
id: create$1()
|
|
2300
|
+
};
|
|
2301
|
+
const {
|
|
2302
|
+
layout
|
|
2303
|
+
} = state;
|
|
2304
|
+
const {
|
|
2305
|
+
groups
|
|
2306
|
+
} = layout;
|
|
2307
|
+
const updatedGroups = groups.map(group => {
|
|
2308
|
+
if (group.id === groupId) {
|
|
2309
|
+
const newTabs = [...group.tabs, newTab];
|
|
2310
|
+
return {
|
|
2311
|
+
...group,
|
|
2312
|
+
activeTabId: newTab.id,
|
|
2313
|
+
isEmpty: newTabs.length === 0,
|
|
2314
|
+
tabs: newTabs
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
return group;
|
|
2318
|
+
});
|
|
2319
|
+
return {
|
|
2320
|
+
...state,
|
|
2321
|
+
layout: {
|
|
2322
|
+
...layout,
|
|
2323
|
+
groups: updatedGroups
|
|
2324
|
+
}
|
|
2325
|
+
};
|
|
2326
|
+
};
|
|
2327
|
+
|
|
2328
|
+
const newFile = async state => {
|
|
2329
|
+
object(state);
|
|
2330
|
+
const {
|
|
2331
|
+
layout,
|
|
2332
|
+
uid
|
|
2333
|
+
} = state;
|
|
2334
|
+
const {
|
|
2335
|
+
activeGroupId,
|
|
2336
|
+
groups
|
|
2337
|
+
} = layout;
|
|
2338
|
+
|
|
2339
|
+
// Find the active group
|
|
2340
|
+
const activeGroup = activeGroupId === undefined ? groups.find(group => group.focused) : groups.find(group => group.id === activeGroupId);
|
|
2341
|
+
|
|
2342
|
+
// Prepare initial state
|
|
2343
|
+
let newState = state;
|
|
2344
|
+
let targetGroupId;
|
|
2345
|
+
if (activeGroup) {
|
|
2346
|
+
targetGroupId = activeGroup.id;
|
|
2347
|
+
} else {
|
|
2348
|
+
// No active group, create an empty one
|
|
2349
|
+
newState = createEmptyGroup(state, '');
|
|
2350
|
+
const updatedActiveGroupId = newState.layout.activeGroupId;
|
|
2351
|
+
if (!updatedActiveGroupId) {
|
|
2352
|
+
return state;
|
|
2353
|
+
}
|
|
2354
|
+
targetGroupId = updatedActiveGroupId;
|
|
2355
|
+
|
|
2356
|
+
// Remove the tab that createEmptyGroup created, we'll add our own
|
|
2357
|
+
newState = {
|
|
2358
|
+
...newState,
|
|
2359
|
+
layout: {
|
|
2360
|
+
...newState.layout,
|
|
2361
|
+
groups: newState.layout.groups.map(group => {
|
|
2362
|
+
if (group.id === targetGroupId) {
|
|
2363
|
+
return {
|
|
2364
|
+
...group,
|
|
2365
|
+
activeTabId: undefined,
|
|
2366
|
+
tabs: []
|
|
2367
|
+
};
|
|
2368
|
+
}
|
|
2369
|
+
return group;
|
|
2370
|
+
})
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
}
|
|
2374
|
+
|
|
2375
|
+
// Get previous active tab ID for viewlet switching
|
|
2376
|
+
getActiveTabId(newState);
|
|
2377
|
+
|
|
2378
|
+
// Create a new empty tab
|
|
2379
|
+
const tabId = create$1();
|
|
2380
|
+
const editorUid = create$1();
|
|
2381
|
+
const newTab = {
|
|
2382
|
+
editorType: 'text',
|
|
2383
|
+
editorUid,
|
|
2384
|
+
errorMessage: '',
|
|
2385
|
+
icon: '',
|
|
2386
|
+
id: tabId,
|
|
2387
|
+
isDirty: false,
|
|
2388
|
+
language: 'plaintext',
|
|
2389
|
+
loadingState: 'loading',
|
|
2390
|
+
title: 'Untitled',
|
|
2391
|
+
uri: 'untitled:///1'
|
|
2392
|
+
};
|
|
2393
|
+
const stateWithNewTab = openTab(newState, targetGroupId, newTab);
|
|
2394
|
+
|
|
2395
|
+
// Calculate bounds: use main area bounds minus tab height
|
|
2396
|
+
const bounds = {
|
|
2397
|
+
height: stateWithNewTab.height - stateWithNewTab.tabHeight,
|
|
2398
|
+
width: stateWithNewTab.width,
|
|
2399
|
+
x: stateWithNewTab.x,
|
|
2400
|
+
y: stateWithNewTab.y + stateWithNewTab.tabHeight
|
|
2401
|
+
};
|
|
2402
|
+
const stateWithViewlet = createViewletForTab(stateWithNewTab, tabId);
|
|
2403
|
+
let intermediateState = stateWithViewlet;
|
|
2404
|
+
|
|
2405
|
+
// Switch viewlet (detach old, attach new if ready)
|
|
2406
|
+
const {
|
|
2407
|
+
newState: switchedState
|
|
2408
|
+
} = switchViewlet(intermediateState);
|
|
2409
|
+
intermediateState = switchedState;
|
|
2410
|
+
set(uid, state, intermediateState);
|
|
2411
|
+
|
|
2412
|
+
// Get the tab to extract editorUid
|
|
2413
|
+
const tabWithViewlet = findTabById(intermediateState, tabId);
|
|
2414
|
+
if (!tabWithViewlet) {
|
|
2415
|
+
return intermediateState;
|
|
2416
|
+
}
|
|
2417
|
+
const {
|
|
2418
|
+
editorUid: actualEditorUid
|
|
2419
|
+
} = tabWithViewlet.tab;
|
|
2420
|
+
if (actualEditorUid === -1) {
|
|
2421
|
+
throw new Error(`invalid editorUid`);
|
|
2422
|
+
}
|
|
2423
|
+
await createViewlet('Editor', actualEditorUid, tabId, bounds, newTab.uri || '');
|
|
2424
|
+
|
|
2425
|
+
// After viewlet is created, get the latest state and mark it as ready
|
|
2426
|
+
const {
|
|
2427
|
+
newState: latestState
|
|
2428
|
+
} = get(uid);
|
|
2429
|
+
const readyState = handleViewletReady(latestState, actualEditorUid);
|
|
2430
|
+
return readyState;
|
|
2431
|
+
};
|
|
2432
|
+
|
|
2433
|
+
const handleHeaderDoubleClick = async (state, className, groupIndexRaw) => {
|
|
2434
|
+
if (className !== MainTabs) {
|
|
2435
|
+
return state;
|
|
2436
|
+
}
|
|
2437
|
+
return newFile(state);
|
|
2438
|
+
};
|
|
2439
|
+
|
|
2165
2440
|
const handleModifiedStatusChange = (state, uri, newStatus) => {
|
|
2166
2441
|
const {
|
|
2167
2442
|
layout
|
|
@@ -2249,7 +2524,7 @@ const getIconsCached = (dirents, fileIconCache) => {
|
|
|
2249
2524
|
return dirents.map(dirent => fileIconCache[dirent]);
|
|
2250
2525
|
};
|
|
2251
2526
|
|
|
2252
|
-
const getBasename
|
|
2527
|
+
const getBasename = uri => {
|
|
2253
2528
|
const lastSlashIndex = uri.lastIndexOf('/');
|
|
2254
2529
|
if (lastSlashIndex === -1) {
|
|
2255
2530
|
return uri;
|
|
@@ -2268,7 +2543,7 @@ const getMissingTabs = (tabs, fileIconCache) => {
|
|
|
2268
2543
|
const tabToIconRequest = tab => {
|
|
2269
2544
|
const uri = tab.uri || '';
|
|
2270
2545
|
return {
|
|
2271
|
-
name: getBasename
|
|
2546
|
+
name: getBasename(uri),
|
|
2272
2547
|
path: uri,
|
|
2273
2548
|
type: 0 // file type
|
|
2274
2549
|
};
|
|
@@ -2371,23 +2646,6 @@ const loadFileIcons = async state => {
|
|
|
2371
2646
|
}
|
|
2372
2647
|
};
|
|
2373
2648
|
|
|
2374
|
-
const getBasename = uri => {
|
|
2375
|
-
const lastSlashIndex = uri.lastIndexOf('/');
|
|
2376
|
-
if (lastSlashIndex === -1) {
|
|
2377
|
-
return uri;
|
|
2378
|
-
}
|
|
2379
|
-
return uri.slice(lastSlashIndex + 1);
|
|
2380
|
-
};
|
|
2381
|
-
const getLabel = uri => {
|
|
2382
|
-
if (uri.startsWith('settings://')) {
|
|
2383
|
-
return 'Settings';
|
|
2384
|
-
}
|
|
2385
|
-
if (uri.startsWith('simple-browser://')) {
|
|
2386
|
-
return 'Simple Browser';
|
|
2387
|
-
}
|
|
2388
|
-
return getBasename(uri);
|
|
2389
|
-
};
|
|
2390
|
-
|
|
2391
2649
|
const handleUriChange = async (state, oldUri, newUri) => {
|
|
2392
2650
|
const {
|
|
2393
2651
|
layout
|
|
@@ -2616,12 +2874,14 @@ const loadContent = async (state, savedState) => {
|
|
|
2616
2874
|
const finalState = {
|
|
2617
2875
|
...editorState,
|
|
2618
2876
|
fileIconCache,
|
|
2877
|
+
initial: false,
|
|
2619
2878
|
layout: updatedLayout
|
|
2620
2879
|
};
|
|
2621
2880
|
return finalState;
|
|
2622
2881
|
}
|
|
2623
2882
|
return {
|
|
2624
2883
|
...state,
|
|
2884
|
+
initial: false,
|
|
2625
2885
|
layout: {
|
|
2626
2886
|
activeGroupId: undefined,
|
|
2627
2887
|
direction: 'horizontal',
|
|
@@ -2656,6 +2916,8 @@ const Close = 'Close';
|
|
|
2656
2916
|
const CloseAll = 'Close All';
|
|
2657
2917
|
const CloseOthers = 'Close Others';
|
|
2658
2918
|
const CloseToTheRight = 'Close To The Right';
|
|
2919
|
+
const CopyPath = 'Copy Path';
|
|
2920
|
+
const CopyRelativePath = 'Copy Relative Path';
|
|
2659
2921
|
const FindFileReferences = 'Find File References';
|
|
2660
2922
|
const RevealInExplorer = 'Reveal in Explorer';
|
|
2661
2923
|
const SplitEditorGroup = 'Split Editor Group';
|
|
@@ -2681,6 +2943,12 @@ const closeToTheRight = () => {
|
|
|
2681
2943
|
const findFileReferences = () => {
|
|
2682
2944
|
return i18nString(FindFileReferences);
|
|
2683
2945
|
};
|
|
2946
|
+
const copyPath = () => {
|
|
2947
|
+
return i18nString(CopyPath);
|
|
2948
|
+
};
|
|
2949
|
+
const copyRelativePath = () => {
|
|
2950
|
+
return i18nString(CopyRelativePath);
|
|
2951
|
+
};
|
|
2684
2952
|
|
|
2685
2953
|
const menuEntrySeparator = {
|
|
2686
2954
|
command: '',
|
|
@@ -2738,6 +3006,18 @@ const getMenuEntries$1 = state => {
|
|
|
2738
3006
|
flags: None,
|
|
2739
3007
|
id: 'revealInExplorer',
|
|
2740
3008
|
label: revealInExplorer()
|
|
3009
|
+
}, {
|
|
3010
|
+
args: [path],
|
|
3011
|
+
command: 'Main.copyPath',
|
|
3012
|
+
flags: None,
|
|
3013
|
+
id: 'copyPath',
|
|
3014
|
+
label: copyPath()
|
|
3015
|
+
}, {
|
|
3016
|
+
args: [path],
|
|
3017
|
+
command: 'Main.copyRelativePath',
|
|
3018
|
+
flags: None,
|
|
3019
|
+
id: 'copyRelativePath',
|
|
3020
|
+
label: copyRelativePath()
|
|
2741
3021
|
}, menuEntrySeparator, {
|
|
2742
3022
|
args: [/* id */'References', /* focus */true, path],
|
|
2743
3023
|
command: 'SideBar.show',
|
|
@@ -2756,196 +3036,6 @@ const getMenuEntries = async (state, props) => {
|
|
|
2756
3036
|
}
|
|
2757
3037
|
};
|
|
2758
3038
|
|
|
2759
|
-
const createEmptyGroup = (state, uri, requestId) => {
|
|
2760
|
-
const {
|
|
2761
|
-
layout
|
|
2762
|
-
} = state;
|
|
2763
|
-
const {
|
|
2764
|
-
groups
|
|
2765
|
-
} = layout;
|
|
2766
|
-
const groupId = create$1();
|
|
2767
|
-
const title = getLabel(uri);
|
|
2768
|
-
const tabId = create$1();
|
|
2769
|
-
const editorUid = create$1();
|
|
2770
|
-
const newTab = {
|
|
2771
|
-
editorType: 'text',
|
|
2772
|
-
editorUid,
|
|
2773
|
-
errorMessage: '',
|
|
2774
|
-
icon: '',
|
|
2775
|
-
id: tabId,
|
|
2776
|
-
isDirty: false,
|
|
2777
|
-
language: '',
|
|
2778
|
-
loadingState: 'loading',
|
|
2779
|
-
title,
|
|
2780
|
-
uri
|
|
2781
|
-
};
|
|
2782
|
-
const newGroup = {
|
|
2783
|
-
activeTabId: newTab.id,
|
|
2784
|
-
focused: true,
|
|
2785
|
-
id: groupId,
|
|
2786
|
-
isEmpty: false,
|
|
2787
|
-
size: 100,
|
|
2788
|
-
tabs: [newTab]
|
|
2789
|
-
};
|
|
2790
|
-
return {
|
|
2791
|
-
...state,
|
|
2792
|
-
layout: {
|
|
2793
|
-
...layout,
|
|
2794
|
-
activeGroupId: groupId,
|
|
2795
|
-
groups: [...groups, newGroup]
|
|
2796
|
-
}
|
|
2797
|
-
};
|
|
2798
|
-
};
|
|
2799
|
-
|
|
2800
|
-
const getActiveTabId = state => {
|
|
2801
|
-
const {
|
|
2802
|
-
layout
|
|
2803
|
-
} = state;
|
|
2804
|
-
const {
|
|
2805
|
-
activeGroupId,
|
|
2806
|
-
groups
|
|
2807
|
-
} = layout;
|
|
2808
|
-
const activeGroup = groups.find(g => g.id === activeGroupId);
|
|
2809
|
-
return activeGroup?.activeTabId;
|
|
2810
|
-
};
|
|
2811
|
-
|
|
2812
|
-
const openTab = (state, groupId, tab) => {
|
|
2813
|
-
const newTab = 'id' in tab && tab.id !== undefined ? tab : {
|
|
2814
|
-
...tab,
|
|
2815
|
-
id: create$1()
|
|
2816
|
-
};
|
|
2817
|
-
const {
|
|
2818
|
-
layout
|
|
2819
|
-
} = state;
|
|
2820
|
-
const {
|
|
2821
|
-
groups
|
|
2822
|
-
} = layout;
|
|
2823
|
-
const updatedGroups = groups.map(group => {
|
|
2824
|
-
if (group.id === groupId) {
|
|
2825
|
-
const newTabs = [...group.tabs, newTab];
|
|
2826
|
-
return {
|
|
2827
|
-
...group,
|
|
2828
|
-
activeTabId: newTab.id,
|
|
2829
|
-
isEmpty: newTabs.length === 0,
|
|
2830
|
-
tabs: newTabs
|
|
2831
|
-
};
|
|
2832
|
-
}
|
|
2833
|
-
return group;
|
|
2834
|
-
});
|
|
2835
|
-
return {
|
|
2836
|
-
...state,
|
|
2837
|
-
layout: {
|
|
2838
|
-
...layout,
|
|
2839
|
-
groups: updatedGroups
|
|
2840
|
-
}
|
|
2841
|
-
};
|
|
2842
|
-
};
|
|
2843
|
-
|
|
2844
|
-
const newFile = async state => {
|
|
2845
|
-
object(state);
|
|
2846
|
-
const {
|
|
2847
|
-
layout,
|
|
2848
|
-
uid
|
|
2849
|
-
} = state;
|
|
2850
|
-
const {
|
|
2851
|
-
activeGroupId,
|
|
2852
|
-
groups
|
|
2853
|
-
} = layout;
|
|
2854
|
-
|
|
2855
|
-
// Find the active group
|
|
2856
|
-
const activeGroup = activeGroupId === undefined ? groups.find(group => group.focused) : groups.find(group => group.id === activeGroupId);
|
|
2857
|
-
|
|
2858
|
-
// Prepare initial state
|
|
2859
|
-
let newState = state;
|
|
2860
|
-
let targetGroupId;
|
|
2861
|
-
if (activeGroup) {
|
|
2862
|
-
targetGroupId = activeGroup.id;
|
|
2863
|
-
} else {
|
|
2864
|
-
// No active group, create an empty one
|
|
2865
|
-
newState = createEmptyGroup(state, '');
|
|
2866
|
-
const updatedActiveGroupId = newState.layout.activeGroupId;
|
|
2867
|
-
if (!updatedActiveGroupId) {
|
|
2868
|
-
return state;
|
|
2869
|
-
}
|
|
2870
|
-
targetGroupId = updatedActiveGroupId;
|
|
2871
|
-
|
|
2872
|
-
// Remove the tab that createEmptyGroup created, we'll add our own
|
|
2873
|
-
newState = {
|
|
2874
|
-
...newState,
|
|
2875
|
-
layout: {
|
|
2876
|
-
...newState.layout,
|
|
2877
|
-
groups: newState.layout.groups.map(group => {
|
|
2878
|
-
if (group.id === targetGroupId) {
|
|
2879
|
-
return {
|
|
2880
|
-
...group,
|
|
2881
|
-
activeTabId: undefined,
|
|
2882
|
-
tabs: []
|
|
2883
|
-
};
|
|
2884
|
-
}
|
|
2885
|
-
return group;
|
|
2886
|
-
})
|
|
2887
|
-
}
|
|
2888
|
-
};
|
|
2889
|
-
}
|
|
2890
|
-
|
|
2891
|
-
// Get previous active tab ID for viewlet switching
|
|
2892
|
-
getActiveTabId(newState);
|
|
2893
|
-
|
|
2894
|
-
// Create a new empty tab
|
|
2895
|
-
const tabId = create$1();
|
|
2896
|
-
const editorUid = create$1();
|
|
2897
|
-
const newTab = {
|
|
2898
|
-
editorType: 'text',
|
|
2899
|
-
editorUid,
|
|
2900
|
-
errorMessage: '',
|
|
2901
|
-
icon: '',
|
|
2902
|
-
id: tabId,
|
|
2903
|
-
isDirty: false,
|
|
2904
|
-
language: 'plaintext',
|
|
2905
|
-
loadingState: 'loading',
|
|
2906
|
-
title: 'Untitled',
|
|
2907
|
-
uri: 'untitled:///1'
|
|
2908
|
-
};
|
|
2909
|
-
const stateWithNewTab = openTab(newState, targetGroupId, newTab);
|
|
2910
|
-
|
|
2911
|
-
// Calculate bounds: use main area bounds minus tab height
|
|
2912
|
-
const bounds = {
|
|
2913
|
-
height: stateWithNewTab.height - stateWithNewTab.tabHeight,
|
|
2914
|
-
width: stateWithNewTab.width,
|
|
2915
|
-
x: stateWithNewTab.x,
|
|
2916
|
-
y: stateWithNewTab.y + stateWithNewTab.tabHeight
|
|
2917
|
-
};
|
|
2918
|
-
const stateWithViewlet = createViewletForTab(stateWithNewTab, tabId);
|
|
2919
|
-
let intermediateState = stateWithViewlet;
|
|
2920
|
-
|
|
2921
|
-
// Switch viewlet (detach old, attach new if ready)
|
|
2922
|
-
const {
|
|
2923
|
-
newState: switchedState
|
|
2924
|
-
} = switchViewlet(intermediateState);
|
|
2925
|
-
intermediateState = switchedState;
|
|
2926
|
-
set(uid, state, intermediateState);
|
|
2927
|
-
|
|
2928
|
-
// Get the tab to extract editorUid
|
|
2929
|
-
const tabWithViewlet = findTabById(intermediateState, tabId);
|
|
2930
|
-
if (!tabWithViewlet) {
|
|
2931
|
-
return intermediateState;
|
|
2932
|
-
}
|
|
2933
|
-
const {
|
|
2934
|
-
editorUid: actualEditorUid
|
|
2935
|
-
} = tabWithViewlet.tab;
|
|
2936
|
-
if (actualEditorUid === -1) {
|
|
2937
|
-
throw new Error(`invalid editorUid`);
|
|
2938
|
-
}
|
|
2939
|
-
await createViewlet('Editor', actualEditorUid, tabId, bounds, newTab.uri || '');
|
|
2940
|
-
|
|
2941
|
-
// After viewlet is created, get the latest state and mark it as ready
|
|
2942
|
-
const {
|
|
2943
|
-
newState: latestState
|
|
2944
|
-
} = get(uid);
|
|
2945
|
-
const readyState = handleViewletReady(latestState, actualEditorUid);
|
|
2946
|
-
return readyState;
|
|
2947
|
-
};
|
|
2948
|
-
|
|
2949
3039
|
const ensureActiveGroup = (state, uri) => {
|
|
2950
3040
|
// Find the active group (by activeGroupId or focused flag)
|
|
2951
3041
|
const {
|
|
@@ -3114,7 +3204,7 @@ const openUri = async (state, options) => {
|
|
|
3114
3204
|
const tabId = getActiveTabId(newState);
|
|
3115
3205
|
|
|
3116
3206
|
// Save state immediately after adding tab
|
|
3117
|
-
set(uid,
|
|
3207
|
+
set(uid, state, newState);
|
|
3118
3208
|
const viewletModuleId = await getViewletModuleId(uri);
|
|
3119
3209
|
|
|
3120
3210
|
// After async call, get the latest state to account for any concurrent changes
|
|
@@ -3141,7 +3231,7 @@ const openUri = async (state, options) => {
|
|
|
3141
3231
|
newState: switchedState
|
|
3142
3232
|
} = switchViewlet(intermediateState1);
|
|
3143
3233
|
intermediateState1 = switchedState;
|
|
3144
|
-
set(uid,
|
|
3234
|
+
set(uid, state, intermediateState1);
|
|
3145
3235
|
|
|
3146
3236
|
// Get the tab to extract editorUid
|
|
3147
3237
|
const tabWithViewlet = findTabById(intermediateState1, tabId);
|
|
@@ -3166,7 +3256,7 @@ const openUri = async (state, options) => {
|
|
|
3166
3256
|
const readyState = handleViewletReady(latestState, editorUid);
|
|
3167
3257
|
|
|
3168
3258
|
// Save state before async icon request
|
|
3169
|
-
set(uid,
|
|
3259
|
+
set(uid, state, readyState);
|
|
3170
3260
|
|
|
3171
3261
|
// Request file icon for the newly opened tab
|
|
3172
3262
|
try {
|
|
@@ -3199,7 +3289,7 @@ const openUri = async (state, options) => {
|
|
|
3199
3289
|
};
|
|
3200
3290
|
|
|
3201
3291
|
// Save the state with icon update so concurrent calls can see it
|
|
3202
|
-
set(uid,
|
|
3292
|
+
set(uid, state, stateWithIcon);
|
|
3203
3293
|
return stateWithIcon;
|
|
3204
3294
|
}
|
|
3205
3295
|
} catch {
|
|
@@ -3236,6 +3326,7 @@ const NavigateChild = 7;
|
|
|
3236
3326
|
const NavigateParent = 8;
|
|
3237
3327
|
const RemoveChild = 9;
|
|
3238
3328
|
const NavigateSibling = 10;
|
|
3329
|
+
const SetReferenceNodeUid = 11;
|
|
3239
3330
|
|
|
3240
3331
|
const isKey = key => {
|
|
3241
3332
|
return key !== 'type' && key !== 'childCount';
|
|
@@ -3303,6 +3394,16 @@ const compareNodes = (oldNode, newNode) => {
|
|
|
3303
3394
|
if (oldNode.type !== newNode.type) {
|
|
3304
3395
|
return null;
|
|
3305
3396
|
}
|
|
3397
|
+
// Handle reference nodes - special handling for uid changes
|
|
3398
|
+
if (oldNode.type === Reference) {
|
|
3399
|
+
if (oldNode.uid !== newNode.uid) {
|
|
3400
|
+
patches.push({
|
|
3401
|
+
type: SetReferenceNodeUid,
|
|
3402
|
+
uid: newNode.uid
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
return patches;
|
|
3406
|
+
}
|
|
3306
3407
|
// Handle text nodes
|
|
3307
3408
|
if (oldNode.type === Text && newNode.type === Text) {
|
|
3308
3409
|
if (oldNode.text !== newNode.text) {
|
|
@@ -3584,6 +3685,7 @@ const HandleClick = 11;
|
|
|
3584
3685
|
const HandleClickClose = 12;
|
|
3585
3686
|
const HandleClickTab = 13;
|
|
3586
3687
|
const HandleTabContextMenu = 14;
|
|
3688
|
+
const HandleHeaderDoubleClick = 15;
|
|
3587
3689
|
|
|
3588
3690
|
const renderTabActions = (isDirty, tabIndex, groupIndex) => {
|
|
3589
3691
|
if (isDirty) {
|
|
@@ -3683,6 +3785,7 @@ const renderEditorGroupHeader = (group, groupIndex, splitButtonEnabled) => {
|
|
|
3683
3785
|
return [{
|
|
3684
3786
|
childCount: hasActions ? 2 : 1,
|
|
3685
3787
|
className: 'EditorGroupHeader',
|
|
3788
|
+
onDblClick: HandleHeaderDoubleClick,
|
|
3686
3789
|
role: 'none',
|
|
3687
3790
|
type: Div
|
|
3688
3791
|
}, ...getTabsVirtualDom(group, groupIndex, tabsChildCount), ...actions];
|
|
@@ -3716,10 +3819,14 @@ const getMainAreaVirtualDom = (layout, splitButtonEnabled = false) => {
|
|
|
3716
3819
|
|
|
3717
3820
|
const renderItems = (oldState, newState) => {
|
|
3718
3821
|
const {
|
|
3822
|
+
initial,
|
|
3719
3823
|
layout,
|
|
3720
3824
|
splitButtonEnabled,
|
|
3721
3825
|
uid
|
|
3722
3826
|
} = newState;
|
|
3827
|
+
if (initial) {
|
|
3828
|
+
return [SetDom2, uid, []];
|
|
3829
|
+
}
|
|
3723
3830
|
const dom = getMainAreaVirtualDom(layout, splitButtonEnabled);
|
|
3724
3831
|
return [SetDom2, uid, dom];
|
|
3725
3832
|
};
|
|
@@ -3781,6 +3888,9 @@ const renderEventListeners = () => {
|
|
|
3781
3888
|
}, {
|
|
3782
3889
|
name: HandleClickAction,
|
|
3783
3890
|
params: ['handleClickAction', 'event.target.dataset.action', 'event.target.dataset.groupId']
|
|
3891
|
+
}, {
|
|
3892
|
+
name: HandleHeaderDoubleClick,
|
|
3893
|
+
params: ['handleHeaderDoubleClick', 'event.target.className', 'event.target.dataset.groupId']
|
|
3784
3894
|
}];
|
|
3785
3895
|
};
|
|
3786
3896
|
|
|
@@ -3938,9 +4048,14 @@ const commandMap = {
|
|
|
3938
4048
|
'MainArea.closeAll': wrapCommand(closeAll$1),
|
|
3939
4049
|
'MainArea.closeAllEditors': wrapCommand(closeAll$1),
|
|
3940
4050
|
'MainArea.closeFocusedTab': wrapCommand(closeFocusedTab),
|
|
4051
|
+
'MainArea.closeOthers': wrapCommand(closeOtherTabs),
|
|
4052
|
+
'MainArea.copyPath': wrapCommand(copyPath$1),
|
|
4053
|
+
'MainArea.copyRelativePath': wrapCommand(copyRelativePath$1),
|
|
3941
4054
|
'MainArea.create': create,
|
|
3942
4055
|
'MainArea.diff2': diff2,
|
|
4056
|
+
'MainArea.focusNext': wrapCommand(focusNextTab),
|
|
3943
4057
|
'MainArea.focusNextTab': wrapCommand(focusNextTab),
|
|
4058
|
+
'MainArea.focusPrevious': wrapCommand(focusPreviousTab),
|
|
3944
4059
|
'MainArea.focusPreviousTab': wrapCommand(focusPreviousTab),
|
|
3945
4060
|
'MainArea.getCommandIds': getCommandIds,
|
|
3946
4061
|
'MainArea.getMenuEntries': wrapGetter(getMenuEntries),
|
|
@@ -3950,6 +4065,7 @@ const commandMap = {
|
|
|
3950
4065
|
'MainArea.handleClickCloseTab': wrapCommand(handleClickCloseTab),
|
|
3951
4066
|
'MainArea.handleClickTab': wrapCommand(handleClickTab),
|
|
3952
4067
|
'MainArea.handleDoubleClick': wrapCommand(handleDoubleClick),
|
|
4068
|
+
'MainArea.handleHeaderDoubleClick': wrapCommand(handleHeaderDoubleClick),
|
|
3953
4069
|
'MainArea.handleModifiedStatusChange': wrapCommand(handleModifiedStatusChange),
|
|
3954
4070
|
'MainArea.handleResize': wrapCommand(handleResize),
|
|
3955
4071
|
'MainArea.handleTabContextMenu': wrapCommand(handleTabContextMenu),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lvce-editor/main-area-worker",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "7.1.0",
|
|
4
4
|
"description": "Main Area Worker",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
"type": "module",
|
|
12
12
|
"main": "dist/mainAreaWorkerMain.js",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@lvce-editor/virtual-dom-worker": "^6.
|
|
14
|
+
"@lvce-editor/virtual-dom-worker": "^6.11.0"
|
|
15
15
|
}
|
|
16
16
|
}
|