@lvce-editor/main-area-worker 9.14.0 → 9.15.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 +338 -94
- package/package.json +1 -1
|
@@ -1474,6 +1474,16 @@ const writeClipBoardText = async text => {
|
|
|
1474
1474
|
await invoke('ClipBoard.writeText', /* text */text);
|
|
1475
1475
|
};
|
|
1476
1476
|
|
|
1477
|
+
const addClosedTabs = (state, entries) => {
|
|
1478
|
+
if (entries.length === 0) {
|
|
1479
|
+
return state;
|
|
1480
|
+
}
|
|
1481
|
+
return {
|
|
1482
|
+
...state,
|
|
1483
|
+
closedTabs: [...state.closedTabs, ...entries].slice(-20)
|
|
1484
|
+
};
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1477
1487
|
const getGroupIndexById = (state, groupId) => {
|
|
1478
1488
|
const {
|
|
1479
1489
|
layout
|
|
@@ -1528,17 +1538,23 @@ const closeTab = (state, groupId, tabId) => {
|
|
|
1528
1538
|
return state;
|
|
1529
1539
|
}
|
|
1530
1540
|
const group = groups[groupIndex];
|
|
1541
|
+
const tabIndex = group.tabs.findIndex(tab => tab.id === tabId);
|
|
1542
|
+
|
|
1531
1543
|
// Check if the tab exists in the group
|
|
1532
|
-
|
|
1533
|
-
if (!tabWasRemoved) {
|
|
1544
|
+
if (tabIndex === -1) {
|
|
1534
1545
|
return state;
|
|
1535
1546
|
}
|
|
1547
|
+
const stateWithClosedTab = addClosedTabs(state, [{
|
|
1548
|
+
group,
|
|
1549
|
+
groupIndex,
|
|
1550
|
+
tab: group.tabs[tabIndex],
|
|
1551
|
+
tabIndex
|
|
1552
|
+
}]);
|
|
1536
1553
|
const newGroups = groups.map(grp => {
|
|
1537
1554
|
if (grp.id === groupId) {
|
|
1538
1555
|
const newTabs = grp.tabs.filter(tab => tab.id !== tabId);
|
|
1539
1556
|
let newActiveTabId = grp.activeTabId;
|
|
1540
1557
|
if (grp.activeTabId === tabId) {
|
|
1541
|
-
const tabIndex = grp.tabs.findIndex(tab => tab.id === tabId);
|
|
1542
1558
|
if (newTabs.length > 0) {
|
|
1543
1559
|
newActiveTabId = newTabs[Math.min(tabIndex, newTabs.length - 1)].id;
|
|
1544
1560
|
} else {
|
|
@@ -1564,13 +1580,13 @@ const closeTab = (state, groupId, tabId) => {
|
|
|
1564
1580
|
if (remainingGroups.length > 0) {
|
|
1565
1581
|
const redistributedGroups = redistributeSizesWithRounding(remainingGroups);
|
|
1566
1582
|
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0]?.id : activeGroupId;
|
|
1567
|
-
return withGroupsAndActiveGroup(
|
|
1583
|
+
return withGroupsAndActiveGroup(stateWithClosedTab, redistributedGroups, newActiveGroupId);
|
|
1568
1584
|
}
|
|
1569
1585
|
|
|
1570
1586
|
// If no remaining groups, return empty layout
|
|
1571
|
-
return withEmptyGroups(
|
|
1587
|
+
return withEmptyGroups(stateWithClosedTab);
|
|
1572
1588
|
}
|
|
1573
|
-
return withGroups(
|
|
1589
|
+
return withGroups(stateWithClosedTab, newGroups);
|
|
1574
1590
|
};
|
|
1575
1591
|
|
|
1576
1592
|
const findTabInState = (state, groupId, tabId) => {
|
|
@@ -1624,7 +1640,15 @@ const closeActiveEditor = async state => {
|
|
|
1624
1640
|
};
|
|
1625
1641
|
|
|
1626
1642
|
const closeAll$1 = state => {
|
|
1627
|
-
|
|
1643
|
+
const entries = state.layout.groups.flatMap((group, groupIndex) => {
|
|
1644
|
+
return group.tabs.map((tab, tabIndex) => ({
|
|
1645
|
+
group,
|
|
1646
|
+
groupIndex,
|
|
1647
|
+
tab,
|
|
1648
|
+
tabIndex
|
|
1649
|
+
}));
|
|
1650
|
+
});
|
|
1651
|
+
return withEmptyGroups(addClosedTabs(state, entries));
|
|
1628
1652
|
};
|
|
1629
1653
|
|
|
1630
1654
|
const redistributeSizesWithRemainder = groups => {
|
|
@@ -1702,6 +1726,12 @@ const closeOtherTabs = (state, groupId) => {
|
|
|
1702
1726
|
if (activeTabId === undefined) {
|
|
1703
1727
|
return state;
|
|
1704
1728
|
}
|
|
1729
|
+
const closedTabs = group.tabs.map((tab, tabIndex) => ({
|
|
1730
|
+
group,
|
|
1731
|
+
groupIndex: groups.findIndex(g => g.id === targetGroupId),
|
|
1732
|
+
tab,
|
|
1733
|
+
tabIndex
|
|
1734
|
+
})).filter(entry => entry.tab.id !== activeTabId);
|
|
1705
1735
|
const newGroups = groups.map(g => {
|
|
1706
1736
|
if (g.id === targetGroupId) {
|
|
1707
1737
|
const newTabs = g.tabs.filter(tab => tab.id === activeTabId);
|
|
@@ -1715,7 +1745,7 @@ const closeOtherTabs = (state, groupId) => {
|
|
|
1715
1745
|
return g;
|
|
1716
1746
|
});
|
|
1717
1747
|
return {
|
|
1718
|
-
...state,
|
|
1748
|
+
...addClosedTabs(state, closedTabs),
|
|
1719
1749
|
layout: {
|
|
1720
1750
|
...layout,
|
|
1721
1751
|
groups: newGroups
|
|
@@ -1757,8 +1787,16 @@ const closeSaved$1 = state => {
|
|
|
1757
1787
|
const {
|
|
1758
1788
|
groups
|
|
1759
1789
|
} = state.layout;
|
|
1790
|
+
const closedTabs = groups.flatMap((group, groupIndex) => {
|
|
1791
|
+
return group.tabs.map((tab, tabIndex) => ({
|
|
1792
|
+
group,
|
|
1793
|
+
groupIndex,
|
|
1794
|
+
tab,
|
|
1795
|
+
tabIndex
|
|
1796
|
+
})).filter(entry => !entry.tab.isDirty);
|
|
1797
|
+
});
|
|
1760
1798
|
const newGroups = groups.map(closeSavedInGroup);
|
|
1761
|
-
return withGroups(state, newGroups);
|
|
1799
|
+
return withGroups(addClosedTabs(state, closedTabs), newGroups);
|
|
1762
1800
|
};
|
|
1763
1801
|
|
|
1764
1802
|
const closeTabsByUris = (state, uris) => {
|
|
@@ -1811,6 +1849,13 @@ const closeTabsRight = (state, groupId) => {
|
|
|
1811
1849
|
if (newTabs.length === tabs.length) {
|
|
1812
1850
|
return state;
|
|
1813
1851
|
}
|
|
1852
|
+
const groupIndex = groups.findIndex(g => g.id === groupId);
|
|
1853
|
+
const closedTabs = tabs.slice(activeTabIndex + 1).map((tab, index) => ({
|
|
1854
|
+
group,
|
|
1855
|
+
groupIndex,
|
|
1856
|
+
tab,
|
|
1857
|
+
tabIndex: activeTabIndex + index + 1
|
|
1858
|
+
}));
|
|
1814
1859
|
const newGroups = groups.map(g => {
|
|
1815
1860
|
if (g.id === groupId) {
|
|
1816
1861
|
return {
|
|
@@ -1821,7 +1866,7 @@ const closeTabsRight = (state, groupId) => {
|
|
|
1821
1866
|
}
|
|
1822
1867
|
return g;
|
|
1823
1868
|
});
|
|
1824
|
-
return withGroups(state, newGroups);
|
|
1869
|
+
return withGroups(addClosedTabs(state, closedTabs), newGroups);
|
|
1825
1870
|
};
|
|
1826
1871
|
|
|
1827
1872
|
const copyPath$1 = async (state, path) => {
|
|
@@ -1869,6 +1914,7 @@ const {
|
|
|
1869
1914
|
const create$2 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
|
|
1870
1915
|
const state = {
|
|
1871
1916
|
assetDir,
|
|
1917
|
+
closedTabs: [],
|
|
1872
1918
|
fileIconCache: {},
|
|
1873
1919
|
height,
|
|
1874
1920
|
iframes: [],
|
|
@@ -2017,8 +2063,101 @@ const getViewletModuleIdForEditorInput = async editorInput => {
|
|
|
2017
2063
|
}
|
|
2018
2064
|
};
|
|
2019
2065
|
|
|
2066
|
+
const getEditorInputEditorType = editorInput => {
|
|
2067
|
+
switch (editorInput.type) {
|
|
2068
|
+
case 'diff-editor':
|
|
2069
|
+
case 'extension-detail-view':
|
|
2070
|
+
return 'custom';
|
|
2071
|
+
case 'editor':
|
|
2072
|
+
return 'text';
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
|
|
2076
|
+
const getEditorInputUri = editorInput => {
|
|
2077
|
+
switch (editorInput.type) {
|
|
2078
|
+
case 'diff-editor':
|
|
2079
|
+
return `diff://?left=${encodeURIComponent(editorInput.uriLeft)}&right=${encodeURIComponent(editorInput.uriRight)}`;
|
|
2080
|
+
case 'editor':
|
|
2081
|
+
return editorInput.uri;
|
|
2082
|
+
case 'extension-detail-view':
|
|
2083
|
+
return `extension-detail://${editorInput.extensionId}`;
|
|
2084
|
+
}
|
|
2085
|
+
};
|
|
2086
|
+
|
|
2087
|
+
const getEditorInputFromUri = uri => {
|
|
2088
|
+
if (uri.startsWith('diff://?')) {
|
|
2089
|
+
try {
|
|
2090
|
+
const parsed = new URL(uri);
|
|
2091
|
+
const uriLeft = parsed.searchParams.get('left');
|
|
2092
|
+
const uriRight = parsed.searchParams.get('right');
|
|
2093
|
+
if (uriLeft && uriRight) {
|
|
2094
|
+
return {
|
|
2095
|
+
type: 'diff-editor',
|
|
2096
|
+
uriLeft,
|
|
2097
|
+
uriRight
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
} catch {
|
|
2101
|
+
// Ignore malformed legacy URIs and fall back to a text editor input.
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
if (uri.startsWith('extension-detail://')) {
|
|
2105
|
+
const extensionIdWithPath = uri.slice('extension-detail://'.length);
|
|
2106
|
+
const extensionId = extensionIdWithPath.split('/')[0];
|
|
2107
|
+
if (extensionId) {
|
|
2108
|
+
return {
|
|
2109
|
+
extensionId,
|
|
2110
|
+
type: 'extension-detail-view'
|
|
2111
|
+
};
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
return {
|
|
2115
|
+
type: 'editor',
|
|
2116
|
+
uri
|
|
2117
|
+
};
|
|
2118
|
+
};
|
|
2119
|
+
const getNormalizedEditorInput = tab => {
|
|
2120
|
+
const {
|
|
2121
|
+
editorInput: tabEditorInput,
|
|
2122
|
+
uri: tabUri
|
|
2123
|
+
} = tab ?? {};
|
|
2124
|
+
let uri;
|
|
2125
|
+
if (typeof tabUri === 'string') {
|
|
2126
|
+
uri = tabUri;
|
|
2127
|
+
} else if (typeof tabEditorInput?.uri === 'string') {
|
|
2128
|
+
const {
|
|
2129
|
+
uri: tabEditorInputUri
|
|
2130
|
+
} = tabEditorInput;
|
|
2131
|
+
uri = tabEditorInputUri;
|
|
2132
|
+
}
|
|
2133
|
+
if (uri) {
|
|
2134
|
+
const inferredEditorInput = getEditorInputFromUri(uri);
|
|
2135
|
+
if (inferredEditorInput.type !== 'editor') {
|
|
2136
|
+
return inferredEditorInput;
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
return tab?.editorInput;
|
|
2140
|
+
};
|
|
2141
|
+
const normalizeTabEditorInput = tab => {
|
|
2142
|
+
const editorInput = getNormalizedEditorInput(tab);
|
|
2143
|
+
if (!editorInput) {
|
|
2144
|
+
return tab;
|
|
2145
|
+
}
|
|
2146
|
+
const uri = typeof tab?.uri === 'string' ? tab.uri : getEditorInputUri(editorInput);
|
|
2147
|
+
return {
|
|
2148
|
+
...tab,
|
|
2149
|
+
editorInput,
|
|
2150
|
+
editorType: getEditorInputEditorType(editorInput),
|
|
2151
|
+
uri
|
|
2152
|
+
};
|
|
2153
|
+
};
|
|
2154
|
+
const getNormalizedOpenEditorInput = uri => {
|
|
2155
|
+
return getEditorInputFromUri(uri);
|
|
2156
|
+
};
|
|
2157
|
+
|
|
2020
2158
|
const getViewletModuleId = async tab => {
|
|
2021
|
-
|
|
2159
|
+
const normalizedTab = normalizeTabEditorInput(tab);
|
|
2160
|
+
return normalizedTab.editorInput ? getViewletModuleIdForEditorInput(normalizedTab.editorInput) : invoke('Layout.getModuleId', normalizedTab.uri);
|
|
2022
2161
|
};
|
|
2023
2162
|
|
|
2024
2163
|
const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
|
|
@@ -2326,7 +2465,7 @@ const shouldCreateViewletForSelectedTab = tab => {
|
|
|
2326
2465
|
};
|
|
2327
2466
|
|
|
2328
2467
|
const maybeCreateViewletForSelectedTab = async (state, newState, groupIndex, index, tabId, tab, uid, needsLoading, requestId, switchCommands) => {
|
|
2329
|
-
const selectedTab = newState.layout.groups[groupIndex].tabs[index];
|
|
2468
|
+
const selectedTab = normalizeTabEditorInput(newState.layout.groups[groupIndex].tabs[index]);
|
|
2330
2469
|
if (!shouldCreateViewletForSelectedTab(selectedTab)) {
|
|
2331
2470
|
return undefined;
|
|
2332
2471
|
}
|
|
@@ -2397,12 +2536,13 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2397
2536
|
tab,
|
|
2398
2537
|
tabId
|
|
2399
2538
|
} = selectedTabData;
|
|
2539
|
+
const normalizedTab = normalizeTabEditorInput(tab);
|
|
2400
2540
|
const isAlreadyActive = layout.activeGroupId === groupId && group.activeTabId === tabId;
|
|
2401
|
-
if (isAlreadyActive && !shouldLoadContentForTab(
|
|
2541
|
+
if (isAlreadyActive && !shouldLoadContentForTab(normalizedTab)) {
|
|
2402
2542
|
return state;
|
|
2403
2543
|
}
|
|
2404
2544
|
getActiveTabId$1(state);
|
|
2405
|
-
const needsLoading = shouldLoadContentForTab(
|
|
2545
|
+
const needsLoading = shouldLoadContentForTab(normalizedTab);
|
|
2406
2546
|
const requestId = needsLoading ? getNextRequestId() : 0;
|
|
2407
2547
|
const updatedGroups = getUpdatedGroups(groups, groupIndex, needsLoading, tabId);
|
|
2408
2548
|
let newState = {
|
|
@@ -2418,7 +2558,7 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2418
2558
|
newState: stateWithViewlet
|
|
2419
2559
|
} = switchViewlet(newState);
|
|
2420
2560
|
newState = stateWithViewlet;
|
|
2421
|
-
const maybeCreatedState = await maybeCreateViewletForSelectedTab(state, newState, groupIndex, index, tabId,
|
|
2561
|
+
const maybeCreatedState = await maybeCreateViewletForSelectedTab(state, newState, groupIndex, index, tabId, normalizedTab, uid, needsLoading, requestId, switchCommands);
|
|
2422
2562
|
if (maybeCreatedState) {
|
|
2423
2563
|
return maybeCreatedState;
|
|
2424
2564
|
}
|
|
@@ -2426,7 +2566,7 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2426
2566
|
if (switchCommands.length > 0) {
|
|
2427
2567
|
await executeViewletCommands(switchCommands);
|
|
2428
2568
|
}
|
|
2429
|
-
return maybeStartLoading(state, newState, tabId,
|
|
2569
|
+
return maybeStartLoading(state, newState, tabId, normalizedTab, needsLoading, requestId);
|
|
2430
2570
|
};
|
|
2431
2571
|
|
|
2432
2572
|
const focusNextTab = async state => {
|
|
@@ -2543,6 +2683,7 @@ const handleClickTogglePreview = async state => {
|
|
|
2543
2683
|
|
|
2544
2684
|
const CloseGroup = 'close-group';
|
|
2545
2685
|
const RetryOpen = 'retry-open';
|
|
2686
|
+
const RestoreClosedTab = 'restore-closed-tab';
|
|
2546
2687
|
const SplitRight$1 = 'split-right';
|
|
2547
2688
|
const TogglePreview$1 = 'toggle-preview';
|
|
2548
2689
|
|
|
@@ -2573,6 +2714,175 @@ const findTabByUri = (state, uri) => {
|
|
|
2573
2714
|
return undefined;
|
|
2574
2715
|
};
|
|
2575
2716
|
|
|
2717
|
+
const focusGroup = (groups, groupId, activeTabId) => {
|
|
2718
|
+
return groups.map(group => {
|
|
2719
|
+
if (group.id === groupId) {
|
|
2720
|
+
return {
|
|
2721
|
+
...group,
|
|
2722
|
+
activeTabId,
|
|
2723
|
+
focused: true
|
|
2724
|
+
};
|
|
2725
|
+
}
|
|
2726
|
+
return {
|
|
2727
|
+
...group,
|
|
2728
|
+
focused: false
|
|
2729
|
+
};
|
|
2730
|
+
});
|
|
2731
|
+
};
|
|
2732
|
+
const clampIndex = (value, min, max) => {
|
|
2733
|
+
return Math.min(Math.max(value, min), max);
|
|
2734
|
+
};
|
|
2735
|
+
const getRestoredTab = tab => {
|
|
2736
|
+
return {
|
|
2737
|
+
...tab,
|
|
2738
|
+
editorUid: -1,
|
|
2739
|
+
errorMessage: '',
|
|
2740
|
+
loadingState: undefined
|
|
2741
|
+
};
|
|
2742
|
+
};
|
|
2743
|
+
const getStateWithoutLastClosedTab = state => {
|
|
2744
|
+
return {
|
|
2745
|
+
...state,
|
|
2746
|
+
closedTabs: state.closedTabs.slice(0, -1)
|
|
2747
|
+
};
|
|
2748
|
+
};
|
|
2749
|
+
const restoreExistingUri = (state, entry) => {
|
|
2750
|
+
if (!entry.tab.uri) {
|
|
2751
|
+
return undefined;
|
|
2752
|
+
}
|
|
2753
|
+
const existing = findTabByUri(state, entry.tab.uri);
|
|
2754
|
+
if (!existing) {
|
|
2755
|
+
return undefined;
|
|
2756
|
+
}
|
|
2757
|
+
const groupIndex = state.layout.groups.findIndex(group => group.id === existing.groupId);
|
|
2758
|
+
if (groupIndex === -1) {
|
|
2759
|
+
return undefined;
|
|
2760
|
+
}
|
|
2761
|
+
const tabIndex = state.layout.groups[groupIndex].tabs.findIndex(tab => tab.id === existing.tab.id);
|
|
2762
|
+
if (tabIndex === -1) {
|
|
2763
|
+
return undefined;
|
|
2764
|
+
}
|
|
2765
|
+
const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
|
|
2766
|
+
const groups = focusGroup(newStateWithoutClosedTab.layout.groups, existing.groupId, existing.tab.id);
|
|
2767
|
+
return {
|
|
2768
|
+
groupIndex,
|
|
2769
|
+
newState: {
|
|
2770
|
+
...newStateWithoutClosedTab,
|
|
2771
|
+
layout: {
|
|
2772
|
+
...newStateWithoutClosedTab.layout,
|
|
2773
|
+
activeGroupId: existing.groupId,
|
|
2774
|
+
groups
|
|
2775
|
+
}
|
|
2776
|
+
},
|
|
2777
|
+
tabIndex
|
|
2778
|
+
};
|
|
2779
|
+
};
|
|
2780
|
+
const restoreIntoExistingGroup = (state, entry) => {
|
|
2781
|
+
const {
|
|
2782
|
+
groups
|
|
2783
|
+
} = state.layout;
|
|
2784
|
+
const groupIndex = groups.findIndex(group => group.id === entry.group.id);
|
|
2785
|
+
if (groupIndex === -1) {
|
|
2786
|
+
return undefined;
|
|
2787
|
+
}
|
|
2788
|
+
const restoredTab = getRestoredTab(entry.tab);
|
|
2789
|
+
const group = groups[groupIndex];
|
|
2790
|
+
const tabIndex = clampIndex(entry.tabIndex, 0, group.tabs.length);
|
|
2791
|
+
const tabs = [...group.tabs];
|
|
2792
|
+
tabs.splice(tabIndex, 0, restoredTab);
|
|
2793
|
+
const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
|
|
2794
|
+
const updatedGroups = groups.map((currentGroup, index) => {
|
|
2795
|
+
if (index === groupIndex) {
|
|
2796
|
+
return {
|
|
2797
|
+
...currentGroup,
|
|
2798
|
+
activeTabId: restoredTab.id,
|
|
2799
|
+
focused: true,
|
|
2800
|
+
isEmpty: false,
|
|
2801
|
+
tabs
|
|
2802
|
+
};
|
|
2803
|
+
}
|
|
2804
|
+
return {
|
|
2805
|
+
...currentGroup,
|
|
2806
|
+
focused: false
|
|
2807
|
+
};
|
|
2808
|
+
});
|
|
2809
|
+
return {
|
|
2810
|
+
groupIndex,
|
|
2811
|
+
newState: {
|
|
2812
|
+
...newStateWithoutClosedTab,
|
|
2813
|
+
layout: {
|
|
2814
|
+
...newStateWithoutClosedTab.layout,
|
|
2815
|
+
activeGroupId: group.id,
|
|
2816
|
+
groups: updatedGroups
|
|
2817
|
+
}
|
|
2818
|
+
},
|
|
2819
|
+
tabIndex
|
|
2820
|
+
};
|
|
2821
|
+
};
|
|
2822
|
+
const createRestoredGroup = entry => {
|
|
2823
|
+
return {
|
|
2824
|
+
...entry.group,
|
|
2825
|
+
activeTabId: entry.tab.id,
|
|
2826
|
+
focused: true,
|
|
2827
|
+
isEmpty: false,
|
|
2828
|
+
tabs: [getRestoredTab(entry.tab)]
|
|
2829
|
+
};
|
|
2830
|
+
};
|
|
2831
|
+
const restoreIntoRecreatedGroup = (state, entry) => {
|
|
2832
|
+
const newStateWithoutClosedTab = getStateWithoutLastClosedTab(state);
|
|
2833
|
+
const restoredGroup = createRestoredGroup(entry);
|
|
2834
|
+
const {
|
|
2835
|
+
groups
|
|
2836
|
+
} = newStateWithoutClosedTab.layout;
|
|
2837
|
+
if (groups.length === 0) {
|
|
2838
|
+
return {
|
|
2839
|
+
groupIndex: 0,
|
|
2840
|
+
newState: {
|
|
2841
|
+
...newStateWithoutClosedTab,
|
|
2842
|
+
layout: {
|
|
2843
|
+
...newStateWithoutClosedTab.layout,
|
|
2844
|
+
activeGroupId: restoredGroup.id,
|
|
2845
|
+
groups: [restoredGroup]
|
|
2846
|
+
}
|
|
2847
|
+
},
|
|
2848
|
+
tabIndex: 0
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
const groupIndex = clampIndex(entry.groupIndex, 0, groups.length);
|
|
2852
|
+
const unfocusedGroups = groups.map(group => ({
|
|
2853
|
+
...group,
|
|
2854
|
+
focused: false
|
|
2855
|
+
}));
|
|
2856
|
+
const insertedGroups = [...unfocusedGroups.slice(0, groupIndex), restoredGroup, ...unfocusedGroups.slice(groupIndex)];
|
|
2857
|
+
return {
|
|
2858
|
+
groupIndex,
|
|
2859
|
+
newState: {
|
|
2860
|
+
...newStateWithoutClosedTab,
|
|
2861
|
+
layout: {
|
|
2862
|
+
...newStateWithoutClosedTab.layout,
|
|
2863
|
+
activeGroupId: restoredGroup.id,
|
|
2864
|
+
groups: redistributeSizesWithRounding(insertedGroups)
|
|
2865
|
+
}
|
|
2866
|
+
},
|
|
2867
|
+
tabIndex: 0
|
|
2868
|
+
};
|
|
2869
|
+
};
|
|
2870
|
+
const restoreClosedTabState = state => {
|
|
2871
|
+
const entry = state.closedTabs.at(-1);
|
|
2872
|
+
if (!entry) {
|
|
2873
|
+
return undefined;
|
|
2874
|
+
}
|
|
2875
|
+
return restoreExistingUri(state, entry) || restoreIntoExistingGroup(state, entry) || restoreIntoRecreatedGroup(state, entry);
|
|
2876
|
+
};
|
|
2877
|
+
|
|
2878
|
+
const restoreClosedTab = async state => {
|
|
2879
|
+
const restored = restoreClosedTabState(state);
|
|
2880
|
+
if (!restored) {
|
|
2881
|
+
return state;
|
|
2882
|
+
}
|
|
2883
|
+
return selectTab(restored.newState, restored.groupIndex, restored.tabIndex);
|
|
2884
|
+
};
|
|
2885
|
+
|
|
2576
2886
|
const focusEditorGroup = (state, groupId) => {
|
|
2577
2887
|
const {
|
|
2578
2888
|
layout
|
|
@@ -2627,16 +2937,6 @@ const getCurrentState = state => {
|
|
|
2627
2937
|
return state;
|
|
2628
2938
|
};
|
|
2629
2939
|
|
|
2630
|
-
const getEditorInputEditorType = editorInput => {
|
|
2631
|
-
switch (editorInput.type) {
|
|
2632
|
-
case 'diff-editor':
|
|
2633
|
-
case 'extension-detail-view':
|
|
2634
|
-
return 'custom';
|
|
2635
|
-
case 'editor':
|
|
2636
|
-
return 'text';
|
|
2637
|
-
}
|
|
2638
|
-
};
|
|
2639
|
-
|
|
2640
2940
|
const getBasename$1 = uri => {
|
|
2641
2941
|
const lastSlashIndex = uri.lastIndexOf('/');
|
|
2642
2942
|
if (lastSlashIndex === -1) {
|
|
@@ -2686,17 +2986,6 @@ const getEditorInputTitle = editorInput => {
|
|
|
2686
2986
|
}
|
|
2687
2987
|
};
|
|
2688
2988
|
|
|
2689
|
-
const getEditorInputUri = editorInput => {
|
|
2690
|
-
switch (editorInput.type) {
|
|
2691
|
-
case 'diff-editor':
|
|
2692
|
-
return `diff://?left=${encodeURIComponent(editorInput.uriLeft)}&right=${encodeURIComponent(editorInput.uriRight)}`;
|
|
2693
|
-
case 'editor':
|
|
2694
|
-
return editorInput.uri;
|
|
2695
|
-
case 'extension-detail-view':
|
|
2696
|
-
return `extension-detail://${editorInput.extensionId}`;
|
|
2697
|
-
}
|
|
2698
|
-
};
|
|
2699
|
-
|
|
2700
2989
|
const createEmptyGroup = (state, uri, requestId, preview = false, title = getLabel(uri), editorType = 'text', editorInput) => {
|
|
2701
2990
|
const {
|
|
2702
2991
|
layout
|
|
@@ -3158,62 +3447,6 @@ const getOptionUriOptions = options => {
|
|
|
3158
3447
|
return options.uri;
|
|
3159
3448
|
};
|
|
3160
3449
|
|
|
3161
|
-
const getEditorInputFromUri = uri => {
|
|
3162
|
-
if (uri.startsWith('diff://?')) {
|
|
3163
|
-
try {
|
|
3164
|
-
const parsed = new URL(uri);
|
|
3165
|
-
const uriLeft = parsed.searchParams.get('left');
|
|
3166
|
-
const uriRight = parsed.searchParams.get('right');
|
|
3167
|
-
if (uriLeft && uriRight) {
|
|
3168
|
-
return {
|
|
3169
|
-
type: 'diff-editor',
|
|
3170
|
-
uriLeft,
|
|
3171
|
-
uriRight
|
|
3172
|
-
};
|
|
3173
|
-
}
|
|
3174
|
-
} catch {
|
|
3175
|
-
// Ignore malformed legacy URIs and fall back to a text editor input.
|
|
3176
|
-
}
|
|
3177
|
-
}
|
|
3178
|
-
if (uri.startsWith('extension-detail://')) {
|
|
3179
|
-
const extensionIdWithPath = uri.slice('extension-detail://'.length);
|
|
3180
|
-
const extensionId = extensionIdWithPath.split('/')[0];
|
|
3181
|
-
if (extensionId) {
|
|
3182
|
-
return {
|
|
3183
|
-
extensionId,
|
|
3184
|
-
type: 'extension-detail-view'
|
|
3185
|
-
};
|
|
3186
|
-
}
|
|
3187
|
-
}
|
|
3188
|
-
return {
|
|
3189
|
-
type: 'editor',
|
|
3190
|
-
uri
|
|
3191
|
-
};
|
|
3192
|
-
};
|
|
3193
|
-
const getNormalizedEditorInput = tab => {
|
|
3194
|
-
if (typeof tab?.uri === 'string') {
|
|
3195
|
-
const inferredEditorInput = getEditorInputFromUri(tab.uri);
|
|
3196
|
-
if (inferredEditorInput.type !== 'editor') {
|
|
3197
|
-
return inferredEditorInput;
|
|
3198
|
-
}
|
|
3199
|
-
}
|
|
3200
|
-
return tab?.editorInput;
|
|
3201
|
-
};
|
|
3202
|
-
const normalizeTabEditorInput = tab => {
|
|
3203
|
-
const editorInput = getNormalizedEditorInput(tab);
|
|
3204
|
-
if (!editorInput) {
|
|
3205
|
-
return tab;
|
|
3206
|
-
}
|
|
3207
|
-
return {
|
|
3208
|
-
...tab,
|
|
3209
|
-
editorInput,
|
|
3210
|
-
editorType: getEditorInputEditorType(editorInput)
|
|
3211
|
-
};
|
|
3212
|
-
};
|
|
3213
|
-
const getNormalizedOpenEditorInput = uri => {
|
|
3214
|
-
return getEditorInputFromUri(uri);
|
|
3215
|
-
};
|
|
3216
|
-
|
|
3217
3450
|
const openUri = async (state, options) => {
|
|
3218
3451
|
const uri = getOptionUriOptions(options);
|
|
3219
3452
|
const preview = typeof options === 'string' ? false : options.preview ?? false;
|
|
@@ -3445,6 +3678,9 @@ const handleClickAction = async (state, action, rawGroupId) => {
|
|
|
3445
3678
|
if (!action) {
|
|
3446
3679
|
return state;
|
|
3447
3680
|
}
|
|
3681
|
+
if (action === RestoreClosedTab) {
|
|
3682
|
+
return restoreClosedTab(state);
|
|
3683
|
+
}
|
|
3448
3684
|
if (activeGroupId === undefined) {
|
|
3449
3685
|
return state;
|
|
3450
3686
|
}
|
|
@@ -4141,7 +4377,12 @@ const getViewletModuleIds = async layout => {
|
|
|
4141
4377
|
} = group;
|
|
4142
4378
|
const activeTab = tabs.find(tab => tab.id === group.activeTabId);
|
|
4143
4379
|
if (activeTab && (activeTab.editorInput || activeTab.uri)) {
|
|
4144
|
-
const
|
|
4380
|
+
const normalizedTab = normalizeTabEditorInput(activeTab);
|
|
4381
|
+
const {
|
|
4382
|
+
editorInput,
|
|
4383
|
+
uri
|
|
4384
|
+
} = normalizedTab;
|
|
4385
|
+
const viewletModuleId = normalizedTab.editorInput ? await getViewletModuleIdForEditorInput(editorInput) : await getViewletModuleId$1(uri);
|
|
4145
4386
|
if (viewletModuleId) {
|
|
4146
4387
|
viewletModuleIds[activeTab.id] = viewletModuleId;
|
|
4147
4388
|
}
|
|
@@ -5833,7 +6074,9 @@ const commandMap = {
|
|
|
5833
6074
|
'Main.openInput': wrapCommand(openInput),
|
|
5834
6075
|
'Main.openUri': wrapCommand(openUri),
|
|
5835
6076
|
'Main.openUris': wrapCommand(openUris),
|
|
6077
|
+
'Main.restoreClosedTab': wrapCommand(restoreClosedTab),
|
|
5836
6078
|
'Main.save': wrapCommand(save),
|
|
6079
|
+
'Main.saveState': wrapGetter(saveState),
|
|
5837
6080
|
'Main.splitRight': wrapCommand(splitRight),
|
|
5838
6081
|
'MainArea.closeActiveEditor': wrapCommand(closeActiveEditor),
|
|
5839
6082
|
'MainArea.closeAll': wrapCommand(closeAll$1),
|
|
@@ -5884,6 +6127,7 @@ const commandMap = {
|
|
|
5884
6127
|
'MainArea.render2': render2,
|
|
5885
6128
|
'MainArea.renderEventListeners': renderEventListeners,
|
|
5886
6129
|
'MainArea.resize': wrapGetter(handleResize),
|
|
6130
|
+
'MainArea.restoreClosedTab': wrapCommand(restoreClosedTab),
|
|
5887
6131
|
'MainArea.save': wrapCommand(save),
|
|
5888
6132
|
'MainArea.saveState': wrapGetter(saveState),
|
|
5889
6133
|
'MainArea.selectTab': wrapCommand(selectTab),
|