@lvce-editor/main-area-worker 9.28.0 → 9.28.2

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.
@@ -2295,7 +2295,21 @@ const closeActiveEditor = async state => {
2295
2295
  return closeTabAndSave(state, focusedGroup.id, activeTabId);
2296
2296
  };
2297
2297
 
2298
- const closeAll$1 = state => {
2298
+ const disposeEditors = async editorUids => {
2299
+ // Dispose all child viewlets in the renderer worker
2300
+ for (const editorUid of editorUids) {
2301
+ try {
2302
+ await invoke('Viewlet.dispose', editorUid);
2303
+ } catch {
2304
+ // Silently ignore errors during disposal
2305
+ // Viewlet may already be disposed or renderer worker may not be available
2306
+ }
2307
+ }
2308
+ };
2309
+
2310
+ const closeAll$1 = async state => {
2311
+ const editorUids = state.layout.groups.flatMap(group => group.tabs.map(tab => tab.editorUid)).filter(editorUid => editorUid !== -1);
2312
+ await disposeEditors(editorUids);
2299
2313
  const entries = state.layout.groups.flatMap((group, groupIndex) => {
2300
2314
  return group.tabs.map((tab, tabIndex) => ({
2301
2315
  group,
@@ -2671,6 +2685,7 @@ const getEditorInputEditorType = editorInput => {
2671
2685
  case 'process-explorer':
2672
2686
  case 'running-extensions':
2673
2687
  case 'video':
2688
+ case 'webview':
2674
2689
  return 'custom';
2675
2690
  case 'editor':
2676
2691
  return 'text';
@@ -2684,6 +2699,7 @@ const getEditorInputUri = editorInput => {
2684
2699
  case 'editor':
2685
2700
  case 'image':
2686
2701
  case 'video':
2702
+ case 'webview':
2687
2703
  return editorInput.uri;
2688
2704
  case 'extension-detail-view':
2689
2705
  return `extension-detail://${editorInput.extensionId}`;
@@ -2788,6 +2804,9 @@ const getNormalizedEditorInput = tab => {
2788
2804
  editorInput: tabEditorInput,
2789
2805
  uri: tabUri
2790
2806
  } = tab ?? {};
2807
+ if (tabEditorInput?.type === 'editor' && tabEditorInput.forceText || tabEditorInput?.type === 'webview') {
2808
+ return tabEditorInput;
2809
+ }
2791
2810
  let uri;
2792
2811
  if (typeof tabUri === 'string') {
2793
2812
  uri = tabUri;
@@ -2916,11 +2935,11 @@ const getSelectedTabBounds = state => {
2916
2935
  };
2917
2936
  };
2918
2937
 
2919
- const getViewletModuleId$1 = async uri => {
2938
+ const getViewletModuleId$1 = async (uri, opener) => {
2920
2939
  // Query RendererWorker for viewlet module ID (optional, may fail in tests)
2921
2940
  let viewletModuleId;
2922
2941
  try {
2923
- viewletModuleId = await invoke('Layout.getModuleId', uri);
2942
+ viewletModuleId = opener === undefined ? await invoke('Layout.getModuleId', uri) : await invoke('Layout.getModuleId', uri, opener);
2924
2943
  } catch {
2925
2944
  // Viewlet creation is optional - silently ignore if RendererWorker isn't available
2926
2945
  }
@@ -2939,15 +2958,18 @@ const getViewletModuleIdForEditorInput = async editorInput => {
2939
2958
  case 'diff-editor':
2940
2959
  return DiffEditor;
2941
2960
  case 'editor':
2961
+ return editorInput.forceText ? EditorText : getViewletModuleId$1(editorInput.uri);
2962
+ case 'extension-detail-view':
2963
+ return ExtensionDetail;
2942
2964
  case 'image':
2943
2965
  case 'video':
2944
2966
  return getViewletModuleId$1(editorInput.uri);
2945
- case 'extension-detail-view':
2946
- return ExtensionDetail;
2947
2967
  case 'process-explorer':
2948
2968
  return ProcessExplorer;
2949
2969
  case 'running-extensions':
2950
2970
  return RunningExtensions;
2971
+ case 'webview':
2972
+ return getViewletModuleId$1(editorInput.uri, editorInput.providerId);
2951
2973
  }
2952
2974
  };
2953
2975
 
@@ -3496,6 +3518,7 @@ const getEditorInputTitle = editorInput => {
3496
3518
  case 'editor':
3497
3519
  case 'image':
3498
3520
  case 'video':
3521
+ case 'webview':
3499
3522
  return getLabel(editorInput.uri);
3500
3523
  case 'extension-detail-view':
3501
3524
  return editorInput.extensionId;
@@ -4060,8 +4083,11 @@ const getGroupSegments = (groups, parentDirection) => {
4060
4083
  if (group.direction !== undefined && group.direction !== parentDirection) {
4061
4084
  const startIndex = index;
4062
4085
  const nestedGroups = [group];
4086
+ const {
4087
+ segmentId
4088
+ } = group;
4063
4089
  index++;
4064
- while (index < groups.length && groups[index].direction === group.direction) {
4090
+ while (index < groups.length && groups[index].direction === group.direction && groups[index].segmentId === segmentId) {
4065
4091
  nestedGroups.push(groups[index]);
4066
4092
  index++;
4067
4093
  }
@@ -4153,6 +4179,7 @@ const splitWithinMatchingNestedDirection = (state, groups, sourceGroup, groupId,
4153
4179
  const newGroup = {
4154
4180
  ...baseNewGroup,
4155
4181
  direction: splitLayoutDirection,
4182
+ segmentId: sourceGroup.segmentId,
4156
4183
  size: Number((sourceGroup.size / 2).toFixed(6))
4157
4184
  };
4158
4185
  const insertIndex = isTrailingSplit(direction) ? sourceIndex + 1 : sourceIndex;
@@ -4162,15 +4189,18 @@ const splitWithinMatchingNestedDirection = (state, groups, sourceGroup, groupId,
4162
4189
  const splitStandaloneSourceIntoNestedDirection = (state, groups, sourceGroup, groupId, newGroupId, direction, splitLayoutDirection, baseNewGroup) => {
4163
4190
  const sourceIndex = groups.findIndex(group => group.id === groupId);
4164
4191
  const halfSize = Number((sourceGroup.size / 2).toFixed(6));
4192
+ const segmentId = sourceGroup.segmentId ?? sourceGroup.id;
4165
4193
  const updatedSourceGroup = {
4166
4194
  ...sourceGroup,
4167
4195
  direction: splitLayoutDirection,
4168
4196
  focused: false,
4197
+ segmentId,
4169
4198
  size: halfSize
4170
4199
  };
4171
4200
  const newGroup = {
4172
4201
  ...baseNewGroup,
4173
4202
  direction: splitLayoutDirection,
4203
+ segmentId,
4174
4204
  size: Number((sourceGroup.size - halfSize).toFixed(6))
4175
4205
  };
4176
4206
  const replacementGroups = isTrailingSplit(direction) ? [updatedSourceGroup, newGroup] : [newGroup, updatedSourceGroup];
@@ -4306,7 +4336,10 @@ const handleClickCloseTab = async (state, rawGroupIndex, rawIndex) => {
4306
4336
  return closeTabAndSave(state, groupId, tabId);
4307
4337
  };
4308
4338
 
4309
- const handleClickTab = async (state, groupIndexRaw, indexRaw) => {
4339
+ const handleClickTab = async (state, groupIndexRaw, indexRaw, button = 0) => {
4340
+ if (button !== 0) {
4341
+ return state;
4342
+ }
4310
4343
  if (!groupIndexRaw || !indexRaw) {
4311
4344
  return state;
4312
4345
  }
@@ -4836,7 +4869,7 @@ const isValidTab = tab => {
4836
4869
  };
4837
4870
 
4838
4871
  const isValidEditorGroup = group => {
4839
- return group && typeof group.id === 'number' && Array.isArray(group.tabs) && group.tabs.every(isValidTab) && (group.activeTabId === undefined || typeof group.activeTabId === 'number') && (group.direction === undefined || isLayoutDirection(group.direction)) && typeof group.focused === 'boolean' && typeof group.size === 'number' && group.size > 0 && typeof group.isEmpty === 'boolean';
4872
+ return group && typeof group.id === 'number' && Array.isArray(group.tabs) && group.tabs.every(isValidTab) && (group.activeTabId === undefined || typeof group.activeTabId === 'number') && (group.direction === undefined || isLayoutDirection(group.direction)) && typeof group.focused === 'boolean' && (group.segmentId === undefined || typeof group.segmentId === 'number') && typeof group.size === 'number' && group.size > 0 && typeof group.isEmpty === 'boolean';
4840
4873
  };
4841
4874
 
4842
4875
  const isValidMainAreaLayout = layout => {
@@ -5072,6 +5105,24 @@ const handleWorkspaceChange = async (state, _workspacePath, savedState) => {
5072
5105
  return loadContent(state, savedState);
5073
5106
  };
5074
5107
 
5108
+ const handleWorkspaceRefresh = async (state, deletedUris = []) => {
5109
+ const deleted = new Set(deletedUris);
5110
+ let newState = state;
5111
+ for (const group of state.layout.groups) {
5112
+ for (const tab of group.tabs) {
5113
+ if (tab.editorInput?.type === 'editor' && deleted.has(tab.editorInput.uri)) {
5114
+ newState = await closeTabWithViewlet(newState, group.id, tab.id);
5115
+ }
5116
+ }
5117
+ }
5118
+ return newState;
5119
+ };
5120
+ const handleWorkspaceRefreshWithContext = async (context, deletedUris = []) => {
5121
+ const state = context.getState();
5122
+ const newState = await handleWorkspaceRefresh(state, deletedUris);
5123
+ await context.updateState(() => newState);
5124
+ };
5125
+
5075
5126
  const hasActiveTextEditor = state => {
5076
5127
  const activeTab = getActiveTab(state);
5077
5128
  return activeTab?.tab.editorInput?.type === 'editor';
@@ -5203,7 +5254,7 @@ const copyPath = () => {
5203
5254
  const copyRelativePath = () => {
5204
5255
  return i18nString(CopyRelativePath);
5205
5256
  };
5206
- const reopenEditorWith = () => {
5257
+ const reopenEditorWith$1 = () => {
5207
5258
  return i18nString(ReopenEditorWith);
5208
5259
  };
5209
5260
  const share = () => {
@@ -5370,10 +5421,10 @@ const getMenuEntries$1 = state => {
5370
5421
  id: 'copyRelativePath',
5371
5422
  label: copyRelativePath()
5372
5423
  }, menuEntrySeparator, {
5373
- command: '',
5424
+ command: 'Main.reopenEditorWith',
5374
5425
  flags: None,
5375
5426
  id: 'reopenEditorWith',
5376
- label: reopenEditorWith()
5427
+ label: reopenEditorWith$1()
5377
5428
  }, menuEntrySeparator, {
5378
5429
  command: '',
5379
5430
  flags: None,
@@ -6429,7 +6480,7 @@ const renderEventListeners = () => {
6429
6480
  params: ['handleClickCloseTab', 'event.target.dataset.groupIndex', 'event.target.dataset.index']
6430
6481
  }, {
6431
6482
  name: HandleClickTab,
6432
- params: ['handleClickTab', 'event.target.dataset.groupIndex', 'event.target.dataset.index']
6483
+ params: ['handleClickTab', 'event.target.dataset.groupIndex', 'event.target.dataset.index', Button$1]
6433
6484
  }, {
6434
6485
  name: HandleContextMenu,
6435
6486
  params: ['handleContextMenu', 'event.target.dataset.groupId', ClientX, ClientY],
@@ -6458,6 +6509,101 @@ const renderEventListeners = () => {
6458
6509
  }];
6459
6510
  };
6460
6511
 
6512
+ const getViewProviderEntries = async uri => {
6513
+ const textEditorEntry = {
6514
+ id: 'editor',
6515
+ label: 'Text Editor',
6516
+ type: 'editor'
6517
+ };
6518
+ try {
6519
+ const providers = await invoke('WebView.getWebViews');
6520
+ const matchingProviders = providers.filter(provider => provider?.id && provider.selector?.some(selector => uri.endsWith(selector)));
6521
+ return [textEditorEntry, ...matchingProviders.map(provider => {
6522
+ const titleElement = provider.elements?.find(element => element.type === 'title');
6523
+ return {
6524
+ id: provider.id,
6525
+ label: provider.name || provider.title || titleElement?.value || provider.id,
6526
+ type: 'webview'
6527
+ };
6528
+ })];
6529
+ } catch {
6530
+ return [textEditorEntry];
6531
+ }
6532
+ };
6533
+ const reopenEditorWith = async context => {
6534
+ const initialState = context.getState();
6535
+ const {
6536
+ activeGroupId,
6537
+ groups
6538
+ } = initialState.layout;
6539
+ const activeGroup = groups.find(group => group.id === activeGroupId);
6540
+ const initialTab = activeGroup?.tabs.find(tab => tab.id === activeGroup.activeTabId);
6541
+ if (!initialTab?.uri) {
6542
+ return;
6543
+ }
6544
+ const entries = await getViewProviderEntries(initialTab.uri);
6545
+ const items = entries.map(entry => ({
6546
+ description: '',
6547
+ label: entry.label,
6548
+ value: entry
6549
+ }));
6550
+ const selected = await invoke('ExtensionHostQuickPick.showQuickPick', {
6551
+ items,
6552
+ placeholder: 'Select Editor'
6553
+ });
6554
+ if (!selected) {
6555
+ return;
6556
+ }
6557
+ const editorInput = selected.type === 'editor' ? {
6558
+ forceText: true,
6559
+ type: 'editor',
6560
+ uri: initialTab.uri
6561
+ } : {
6562
+ providerId: selected.id,
6563
+ type: 'webview',
6564
+ uri: initialTab.uri
6565
+ };
6566
+ const viewletModuleId = await getViewletModuleIdForEditorInput(editorInput);
6567
+ if (!viewletModuleId) {
6568
+ return;
6569
+ }
6570
+ const latestState = context.getState();
6571
+ const latestTab = findTabById(latestState, initialTab.id);
6572
+ if (!latestTab) {
6573
+ return;
6574
+ }
6575
+ const oldEditorUid = latestTab.tab.editorUid;
6576
+ const resetState = updateTab(latestState, initialTab.id, {
6577
+ editorInput,
6578
+ editorType: getEditorInputEditorType(editorInput),
6579
+ editorUid: -1,
6580
+ errorMessage: undefined,
6581
+ loadingState: undefined
6582
+ });
6583
+ const bounds = {
6584
+ height: resetState.height - resetState.tabHeight,
6585
+ width: resetState.width,
6586
+ x: resetState.x,
6587
+ y: resetState.y + resetState.tabHeight
6588
+ };
6589
+ const stateWithViewlet = createViewletForTab(resetState, initialTab.id);
6590
+ await context.updateState(() => stateWithViewlet);
6591
+ const tabWithViewlet = findTabById(stateWithViewlet, initialTab.id);
6592
+ if (!tabWithViewlet || tabWithViewlet.tab.editorUid === -1) {
6593
+ return;
6594
+ }
6595
+ const renderedTitle = await createViewlet(viewletModuleId, tabWithViewlet.tab.editorUid, initialTab.id, bounds, initialTab.uri);
6596
+ const readyState = handleViewletReady(context.getState(), tabWithViewlet.tab.editorUid, renderedTitle);
6597
+ await context.updateState(() => readyState);
6598
+ if (oldEditorUid !== -1) {
6599
+ try {
6600
+ await invoke('Viewlet.dispose', oldEditorUid);
6601
+ } catch {
6602
+ // Reopening should still proceed if the previous viewlet was already disposed.
6603
+ }
6604
+ }
6605
+ };
6606
+
6461
6607
  const getLatestStoredState = (uid, fallbackState, referenceTabId, referenceTabUri, allowMissingReference = false) => {
6462
6608
  const stateFromStore = get(uid);
6463
6609
  if (!stateFromStore) {
@@ -6627,6 +6773,7 @@ const setEditorLayout = (state, direction, slots) => {
6627
6773
  ...group,
6628
6774
  direction: slot.direction,
6629
6775
  focused,
6776
+ segmentId: slot.segmentId,
6630
6777
  size: slot.size
6631
6778
  };
6632
6779
  });
@@ -6690,39 +6837,51 @@ const setEditorLayoutThreeRows = state => {
6690
6837
  }]);
6691
6838
  };
6692
6839
  const setEditorLayoutGrid = state => {
6840
+ const leftSegmentId = create$2();
6841
+ const rightSegmentId = create$2();
6693
6842
  return setEditorLayout(state, Horizontal, [{
6694
6843
  direction: Vertical,
6844
+ segmentId: leftSegmentId,
6695
6845
  size: 25
6696
6846
  }, {
6697
6847
  direction: Vertical,
6848
+ segmentId: leftSegmentId,
6698
6849
  size: 25
6699
6850
  }, {
6700
6851
  direction: Vertical,
6852
+ segmentId: rightSegmentId,
6701
6853
  size: 25
6702
6854
  }, {
6703
6855
  direction: Vertical,
6856
+ segmentId: rightSegmentId,
6704
6857
  size: 25
6705
6858
  }]);
6706
6859
  };
6707
6860
  const setEditorLayoutTwoRowsRight = state => {
6861
+ const segmentId = create$2();
6708
6862
  return setEditorLayout(state, Horizontal, [{
6709
6863
  size: 50
6710
6864
  }, {
6711
6865
  direction: Vertical,
6866
+ segmentId,
6712
6867
  size: 25
6713
6868
  }, {
6714
6869
  direction: Vertical,
6870
+ segmentId,
6715
6871
  size: 25
6716
6872
  }]);
6717
6873
  };
6718
6874
  const setEditorLayoutTwoColumnsBottom = state => {
6875
+ const segmentId = create$2();
6719
6876
  return setEditorLayout(state, Vertical, [{
6720
6877
  size: 50
6721
6878
  }, {
6722
6879
  direction: Horizontal,
6880
+ segmentId,
6723
6881
  size: 25
6724
6882
  }, {
6725
6883
  direction: Horizontal,
6884
+ segmentId,
6726
6885
  size: 25
6727
6886
  }]);
6728
6887
  };
@@ -6928,6 +7087,7 @@ const commandMap = {
6928
7087
  'MainArea.handleTabContextMenu': wrapSerialCommand(handleTabContextMenu),
6929
7088
  'MainArea.handleUriChange': wrapSerialCommand(handleUriChange),
6930
7089
  'MainArea.handleWorkspaceChange': wrapSerialCommand(handleWorkspaceChange),
7090
+ 'MainArea.handleWorkspaceRefresh': wrapAsyncCommand(handleWorkspaceRefreshWithContext),
6931
7091
  'MainArea.hasActiveTextEditor': wrapGetter(hasActiveTextEditor),
6932
7092
  'MainArea.initialize': initialize,
6933
7093
  'MainArea.loadContent': wrapSerialCommand(loadContent),
@@ -6940,6 +7100,7 @@ const commandMap = {
6940
7100
  'MainArea.refresh': wrapSerialCommand(refresh),
6941
7101
  'MainArea.render2': render2,
6942
7102
  'MainArea.renderEventListeners': renderEventListeners,
7103
+ 'MainArea.reopenEditorWith': wrapSerialAsyncCommand(reopenEditorWith),
6943
7104
  'MainArea.resize': wrapGetter(handleResize),
6944
7105
  'MainArea.restoreClosedTab': wrapSerialCommand(restoreClosedTab),
6945
7106
  'MainArea.save': wrapSerialCommand(save),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/main-area-worker",
3
- "version": "9.28.0",
3
+ "version": "9.28.2",
4
4
  "description": "Main Area Worker",
5
5
  "repository": {
6
6
  "type": "git",