@codingame/monaco-vscode-views-service-override 2.0.3 → 2.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.
Files changed (65) hide show
  1. package/index.d.ts +1 -1
  2. package/index.js +1 -1
  3. package/package.json +11 -11
  4. package/tools/editor.js +14 -0
  5. package/views.js +12 -5
  6. package/vscode/src/vs/base/common/codicons.d.ts +5 -0
  7. package/vscode/src/vs/workbench/api/browser/viewsExtensionPoint.js +2 -2
  8. package/vscode/src/vs/workbench/browser/actions/listCommands.js +160 -4
  9. package/vscode/src/vs/workbench/browser/parts/activitybar/activitybarPart.js +14 -19
  10. package/vscode/src/vs/workbench/browser/parts/auxiliarybar/media/auxiliaryBarPart.css.js +1 -1
  11. package/vscode/src/vs/workbench/browser/parts/editor/auxiliaryEditorPart.js +59 -21
  12. package/vscode/src/vs/workbench/browser/parts/editor/editor.contribution.js +77 -45
  13. package/vscode/src/vs/workbench/browser/parts/editor/editorConfiguration.js +23 -1
  14. package/vscode/src/vs/workbench/browser/parts/editor/editorPart.js +77 -45
  15. package/vscode/src/vs/workbench/browser/parts/editor/editorParts.js +131 -5
  16. package/vscode/src/vs/workbench/browser/parts/media/paneCompositePart.css.js +1 -1
  17. package/vscode/src/vs/workbench/browser/parts/paneCompositeBar.js +1 -1
  18. package/vscode/src/vs/workbench/browser/parts/paneCompositePart.js +2 -2
  19. package/vscode/src/vs/workbench/browser/parts/sidebar/media/sidebarpart.css.js +1 -1
  20. package/vscode/src/vs/workbench/browser/parts/sidebar/sidebarPart.d.ts +1 -3
  21. package/vscode/src/vs/workbench/browser/parts/sidebar/sidebarPart.js +8 -16
  22. package/vscode/src/vs/workbench/contrib/callHierarchy/browser/callHierarchy.contribution.js +13 -13
  23. package/vscode/src/vs/workbench/contrib/files/browser/editors/textFileEditor.js +8 -3
  24. package/vscode/src/vs/workbench/contrib/files/browser/editors/textFileEditorTracker.js +1 -1
  25. package/vscode/src/vs/workbench/contrib/files/browser/explorerService.js +4 -0
  26. package/vscode/src/vs/workbench/contrib/files/browser/fileActions.contribution.js +2 -2
  27. package/vscode/src/vs/workbench/contrib/files/browser/fileCommands.js +3 -4
  28. package/vscode/src/vs/workbench/contrib/files/browser/files.contribution.js +1 -1
  29. package/vscode/src/vs/workbench/contrib/files/browser/workspaceWatcher.js +1 -1
  30. package/vscode/src/vs/workbench/contrib/files/common/dirtyFilesIndicator.js +1 -1
  31. package/vscode/src/vs/workbench/contrib/mergeEditor/browser/commands/commands.js +17 -16
  32. package/vscode/src/vs/workbench/contrib/mergeEditor/browser/commands/devCommands.js +4 -4
  33. package/vscode/src/vs/workbench/contrib/mergeEditor/browser/view/editors/codeEditorView.js +1 -1
  34. package/vscode/src/vs/workbench/contrib/typeHierarchy/browser/typeHierarchy.contribution.js +13 -13
  35. package/vscode/src/vs/workbench/contrib/webview/browser/webviewElement.js +2 -2
  36. package/vscode/src/vs/workbench/contrib/webviewPanel/browser/webviewPanel.contribution.js +1 -1
  37. package/vscode/src/vs/workbench/contrib/webviewView/browser/webviewViewPane.js +2 -1
  38. package/vscode/src/vs/workbench/services/activity/browser/activityService.js +1 -0
  39. package/vscode/src/vs/workbench/services/editor/browser/editorResolverService.js +18 -4
  40. package/vscode/src/vs/workbench/services/history/browser/historyService.js +2 -2
  41. package/vscode/src/vs/workbench/services/progress/browser/progressService.js +15 -4
  42. package/vscode/src/vs/workbench/services/untitled/common/untitledTextEditorHandler.js +2 -2
  43. package/vscode/src/vs/workbench/services/views/browser/viewDescriptorService.js +6 -2
  44. package/vscode/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.css.js +0 -6
  45. package/vscode/src/vs/base/browser/ui/breadcrumbs/breadcrumbsWidget.js +0 -290
  46. package/vscode/src/vs/workbench/browser/parts/editor/breadcrumbsControl.js +0 -801
  47. package/vscode/src/vs/workbench/browser/parts/editor/breadcrumbsModel.js +0 -142
  48. package/vscode/src/vs/workbench/browser/parts/editor/breadcrumbsPicker.js +0 -412
  49. package/vscode/src/vs/workbench/browser/parts/editor/editorGroupView.js +0 -1315
  50. package/vscode/src/vs/workbench/browser/parts/editor/editorGroupWatermark.js +0 -186
  51. package/vscode/src/vs/workbench/browser/parts/editor/editorPanes.js +0 -346
  52. package/vscode/src/vs/workbench/browser/parts/editor/editorTitleControl.js +0 -154
  53. package/vscode/src/vs/workbench/browser/parts/editor/media/breadcrumbscontrol.css.js +0 -6
  54. package/vscode/src/vs/workbench/browser/parts/editor/media/editorgroupview.css.js +0 -6
  55. package/vscode/src/vs/workbench/browser/parts/editor/media/editortitlecontrol.css.js +0 -6
  56. package/vscode/src/vs/workbench/browser/parts/editor/media/multieditortabscontrol.css.js +0 -6
  57. package/vscode/src/vs/workbench/browser/parts/editor/media/singleeditortabscontrol.css.js +0 -6
  58. package/vscode/src/vs/workbench/browser/parts/editor/multiEditorTabsControl.js +0 -1623
  59. package/vscode/src/vs/workbench/browser/parts/editor/multiRowEditorTabsControl.js +0 -152
  60. package/vscode/src/vs/workbench/browser/parts/editor/noEditorTabsControl.js +0 -54
  61. package/vscode/src/vs/workbench/browser/parts/editor/singleEditorTabsControl.js +0 -259
  62. package/vscode/src/vs/workbench/common/editor/filteredEditorGroupModel.js +0 -109
  63. package/vscode/src/vs/workbench/services/hover/browser/hoverService.js +0 -195
  64. package/vscode/src/vs/workbench/services/hover/browser/hoverWidget.js +0 -528
  65. package/vscode/src/vs/workbench/services/hover/browser/media/hover.css.js +0 -6
@@ -1,1623 +0,0 @@
1
- import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
- import './media/multieditortabscontrol.css.js';
3
- import { isWindows, isMacintosh } from 'vscode/vscode/vs/base/common/platform';
4
- import { shorten } from 'vscode/vscode/vs/base/common/labels';
5
- import { DEFAULT_EDITOR_ASSOCIATION, preventEditorClose, EditorCloseMethod, EditorResourceAccessor, SideBySideEditor } from 'vscode/vscode/vs/workbench/common/editor';
6
- import { computeEditorAriaLabel } from 'vscode/vscode/vs/workbench/browser/editor';
7
- import { StandardKeyboardEvent } from 'vscode/vscode/vs/base/browser/keyboardEvent';
8
- import { Gesture, EventType as EventType$1 } from 'vscode/vscode/vs/base/browser/touch';
9
- import { ResourceLabels, DEFAULT_LABELS_CONTAINER } from 'vscode/vscode/vs/workbench/browser/labels';
10
- import { ActionBar } from 'vscode/vscode/vs/base/browser/ui/actionbar/actionbar';
11
- import { IContextMenuService } from 'vscode/vscode/vs/platform/contextview/browser/contextView';
12
- import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
13
- import { IKeybindingService } from 'vscode/vscode/vs/platform/keybinding/common/keybinding';
14
- import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
15
- import { MenuId } from 'vscode/vscode/vs/platform/actions/common/actions';
16
- import { EditorTabsControl, EditorCommandsContextActionRunner } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorTabsControl';
17
- import { IQuickInputService } from 'vscode/vscode/vs/platform/quickinput/common/quickInput';
18
- import { MutableDisposable, DisposableStore, dispose, combinedDisposable, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
19
- import { ScrollableElement } from 'vscode/vscode/vs/base/browser/ui/scrollbar/scrollableElement';
20
- import { getOrSet } from 'vscode/vscode/vs/base/common/map';
21
- import { registerThemingParticipant, IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
22
- import { TAB_ACTIVE_BACKGROUND, TAB_INACTIVE_BACKGROUND, EDITOR_DRAG_AND_DROP_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BORDER, TAB_BORDER, TAB_UNFOCUSED_ACTIVE_BACKGROUND, TAB_ACTIVE_BORDER, TAB_UNFOCUSED_ACTIVE_BORDER, TAB_ACTIVE_BORDER_TOP, TAB_UNFOCUSED_ACTIVE_BORDER_TOP, TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_BACKGROUND, TAB_INACTIVE_FOREGROUND, TAB_UNFOCUSED_INACTIVE_FOREGROUND, TAB_ACTIVE_MODIFIED_BORDER, TAB_INACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER, TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER, TAB_LAST_PINNED_BORDER, TAB_HOVER_BACKGROUND, TAB_UNFOCUSED_HOVER_BACKGROUND, TAB_HOVER_FOREGROUND, TAB_UNFOCUSED_HOVER_FOREGROUND, TAB_HOVER_BORDER, TAB_UNFOCUSED_HOVER_BORDER, WORKBENCH_BACKGROUND, EDITOR_GROUP_HEADER_TABS_BACKGROUND } from 'vscode/vscode/vs/workbench/common/theme';
23
- import { activeContrastBorder, contrastBorder, editorBackground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
24
- import { DraggedEditorIdentifier, DraggedEditorGroupIdentifier, isWindowDraggedOver, extractTreeDropData, ResourcesDropHandler } from 'vscode/vscode/vs/workbench/browser/dnd';
25
- import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification';
26
- import { Dimension, addDisposableListener, EventType, EventHelper, DragAndDropObserver, clearNode, scheduleAtNextAnimationFrame, getWindow, isMouseEvent, findParentWithClass } from 'vscode/vscode/vs/base/browser/dom';
27
- import { localizeWithPath } from 'vscode/vscode/vs/nls';
28
- import { CloseOneEditorAction, UnpinEditorAction } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorActions';
29
- import { assertAllDefined, assertIsDefined } from 'vscode/vscode/vs/base/common/types';
30
- import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
31
- import { basenameOrAuthority } from 'vscode/vscode/vs/base/common/resources';
32
- import { RunOnceScheduler } from 'vscode/vscode/vs/base/common/async';
33
- import { IPathService } from 'vscode/vscode/vs/workbench/services/path/common/pathService';
34
- import { win32, posix } from 'vscode/vscode/vs/base/common/path';
35
- import { insert, coalesce } from 'vscode/vscode/vs/base/common/arrays';
36
- import { isHighContrast } from 'vscode/vscode/vs/platform/theme/common/theme';
37
- import { isSafari } from 'vscode/vscode/vs/base/browser/browser';
38
- import { equals } from 'vscode/vscode/vs/base/common/objects';
39
- import { EditorActivation } from 'vscode/vscode/vs/platform/editor/common/editor';
40
- import { UNLOCK_GROUP_COMMAND_ID } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorCommands';
41
- import { StandardMouseEvent } from 'vscode/vscode/vs/base/browser/mouseEvent';
42
- import { ITreeViewsDnDService } from 'vscode/vscode/vs/editor/common/services/treeViewsDndService';
43
- import { DraggedTreeItemsIdentifier } from 'vscode/vscode/vs/editor/common/services/treeViewsDnd';
44
- import { IEditorResolverService } from 'vscode/vscode/vs/workbench/services/editor/common/editorResolverService';
45
- import { UnstickyEditorGroupModel, StickyEditorGroupModel } from '../../../common/editor/filteredEditorGroupModel.js';
46
- import { IHostService } from 'vscode/vscode/vs/workbench/services/host/browser/host';
47
-
48
- var MultiEditorTabsControl_1;
49
- let MultiEditorTabsControl = class MultiEditorTabsControl extends EditorTabsControl {
50
- static { MultiEditorTabsControl_1 = this; }
51
- static { this.SCROLLBAR_SIZES = {
52
- default: 3,
53
- large: 10
54
- }; }
55
- static { this.TAB_WIDTH = {
56
- compact: 38,
57
- shrink: 80,
58
- fit: 120
59
- }; }
60
- static { this.DRAG_OVER_OPEN_TAB_THRESHOLD = 1500; }
61
- static { this.MOUSE_WHEEL_EVENT_THRESHOLD = 150; }
62
- static { this.MOUSE_WHEEL_DISTANCE_THRESHOLD = 1.5; }
63
- constructor(parent, editorPartsView, groupsView, groupView, tabsModel, contextMenuService, instantiationService, contextKeyService, keybindingService, notificationService, quickInputService, themeService, editorService, pathService, treeViewsDragAndDropService, editorResolverService, hostService) {
64
- super(parent, editorPartsView, groupsView, groupView, tabsModel, contextMenuService, instantiationService, contextKeyService, keybindingService, notificationService, quickInputService, themeService, editorResolverService, hostService);
65
- this.editorService = editorService;
66
- this.pathService = pathService;
67
- this.treeViewsDragAndDropService = treeViewsDragAndDropService;
68
- this.closeEditorAction = this._register(this.instantiationService.createInstance(CloseOneEditorAction, CloseOneEditorAction.ID, CloseOneEditorAction.LABEL));
69
- this.unpinEditorAction = this._register(this.instantiationService.createInstance(UnpinEditorAction, UnpinEditorAction.ID, UnpinEditorAction.LABEL));
70
- this.tabResourceLabels = this._register(this.instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER));
71
- this.tabLabels = [];
72
- this.tabActionBars = [];
73
- this.tabDisposables = [];
74
- this.dimensions = {
75
- container: Dimension.None,
76
- available: Dimension.None
77
- };
78
- this.layoutScheduler = this._register(( new MutableDisposable()));
79
- this.path = isWindows ? win32 : posix;
80
- this.lastMouseWheelEventTime = 0;
81
- this.isMouseOverTabs = false;
82
- this.updateEditorLabelScheduler = this._register(( new RunOnceScheduler(() => this.doUpdateEditorLabels(), 0)));
83
- (async () => this.path = await this.pathService.path)();
84
- this._register(this.tabResourceLabels.onDidChangeDecorations(() => this.doHandleDecorationsChange()));
85
- }
86
- create(parent) {
87
- super.create(parent);
88
- this.titleContainer = parent;
89
- this.tabsAndActionsContainer = document.createElement('div');
90
- this.tabsAndActionsContainer.classList.add('tabs-and-actions-container');
91
- this.titleContainer.appendChild(this.tabsAndActionsContainer);
92
- this.tabsContainer = document.createElement('div');
93
- this.tabsContainer.setAttribute('role', 'tablist');
94
- this.tabsContainer.draggable = true;
95
- this.tabsContainer.classList.add('tabs-container');
96
- this._register(Gesture.addTarget(this.tabsContainer));
97
- this.tabSizingFixedDisposables = this._register(( new DisposableStore()));
98
- this.updateTabSizing(false);
99
- this.tabsScrollbar = this.createTabsScrollbar(this.tabsContainer);
100
- this.tabsAndActionsContainer.appendChild(this.tabsScrollbar.getDomNode());
101
- this.registerTabsContainerListeners(this.tabsContainer, this.tabsScrollbar);
102
- this.createEditorActionsToolBar(this.tabsAndActionsContainer, ['editor-actions']);
103
- this.updateTabsControlVisibility();
104
- }
105
- createTabsScrollbar(scrollable) {
106
- const tabsScrollbar = this._register(( new ScrollableElement(scrollable, {
107
- horizontal: 1 ,
108
- horizontalScrollbarSize: this.getTabsScrollbarSizing(),
109
- vertical: 2 ,
110
- scrollYToX: true,
111
- useShadows: false
112
- })));
113
- this._register(tabsScrollbar.onScroll(e => {
114
- if (e.scrollLeftChanged) {
115
- scrollable.scrollLeft = e.scrollLeft;
116
- }
117
- }));
118
- return tabsScrollbar;
119
- }
120
- updateTabsScrollbarSizing() {
121
- this.tabsScrollbar?.updateOptions({
122
- horizontalScrollbarSize: this.getTabsScrollbarSizing()
123
- });
124
- }
125
- updateTabSizing(fromEvent) {
126
- const [tabsContainer, tabSizingFixedDisposables] = assertAllDefined(this.tabsContainer, this.tabSizingFixedDisposables);
127
- tabSizingFixedDisposables.clear();
128
- const options = this.groupsView.partOptions;
129
- if (options.tabSizing === 'fixed') {
130
- tabsContainer.style.setProperty('--tab-sizing-fixed-min-width', `${options.tabSizingFixedMinWidth}px`);
131
- tabsContainer.style.setProperty('--tab-sizing-fixed-max-width', `${options.tabSizingFixedMaxWidth}px`);
132
- tabSizingFixedDisposables.add(addDisposableListener(tabsContainer, EventType.MOUSE_ENTER, () => {
133
- this.isMouseOverTabs = true;
134
- }));
135
- tabSizingFixedDisposables.add(addDisposableListener(tabsContainer, EventType.MOUSE_LEAVE, () => {
136
- this.isMouseOverTabs = false;
137
- this.updateTabsFixedWidth(false);
138
- }));
139
- }
140
- else if (fromEvent) {
141
- tabsContainer.style.removeProperty('--tab-sizing-fixed-min-width');
142
- tabsContainer.style.removeProperty('--tab-sizing-fixed-max-width');
143
- this.updateTabsFixedWidth(false);
144
- }
145
- }
146
- updateTabsFixedWidth(fixed) {
147
- this.forEachTab((editor, tabIndex, tabContainer) => {
148
- if (fixed) {
149
- const { width } = tabContainer.getBoundingClientRect();
150
- tabContainer.style.setProperty('--tab-sizing-current-width', `${width}px`);
151
- }
152
- else {
153
- tabContainer.style.removeProperty('--tab-sizing-current-width');
154
- }
155
- });
156
- }
157
- getTabsScrollbarSizing() {
158
- if (this.groupsView.partOptions.titleScrollbarSizing !== 'large') {
159
- return MultiEditorTabsControl_1.SCROLLBAR_SIZES.default;
160
- }
161
- return MultiEditorTabsControl_1.SCROLLBAR_SIZES.large;
162
- }
163
- registerTabsContainerListeners(tabsContainer, tabsScrollbar) {
164
- this._register(addDisposableListener(tabsContainer, EventType.SCROLL, () => {
165
- if (tabsContainer.classList.contains('scroll')) {
166
- tabsScrollbar.setScrollPosition({
167
- scrollLeft: tabsContainer.scrollLeft
168
- });
169
- }
170
- }));
171
- for (const eventType of [EventType$1.Tap, EventType.DBLCLICK]) {
172
- this._register(addDisposableListener(tabsContainer, eventType, (e) => {
173
- if (eventType === EventType.DBLCLICK) {
174
- if (e.target !== tabsContainer) {
175
- return;
176
- }
177
- }
178
- else {
179
- if (e.tapCount !== 2) {
180
- return;
181
- }
182
- if (e.initialTarget !== tabsContainer) {
183
- return;
184
- }
185
- }
186
- EventHelper.stop(e);
187
- this.editorService.openEditor({
188
- resource: undefined,
189
- options: {
190
- pinned: true,
191
- index: this.groupView.count,
192
- override: DEFAULT_EDITOR_ASSOCIATION.id
193
- }
194
- }, this.groupView.id);
195
- }));
196
- }
197
- this._register(addDisposableListener(tabsContainer, EventType.MOUSE_DOWN, e => {
198
- if (e.button === 1) {
199
- e.preventDefault();
200
- }
201
- }));
202
- let lastDragEvent = undefined;
203
- this._register(( new DragAndDropObserver(tabsContainer, {
204
- onDragStart: e => {
205
- this.onGroupDragStart(e, tabsContainer);
206
- },
207
- onDrag: e => {
208
- lastDragEvent = e;
209
- },
210
- onDragEnter: e => {
211
- tabsContainer.classList.add('scroll');
212
- if (e.target !== tabsContainer) {
213
- this.updateDropFeedback(tabsContainer, false);
214
- return;
215
- }
216
- if (!this.isSupportedDropTransfer(e)) {
217
- if (e.dataTransfer) {
218
- e.dataTransfer.dropEffect = 'none';
219
- }
220
- return;
221
- }
222
- let isLocalDragAndDrop = false;
223
- if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) {
224
- isLocalDragAndDrop = true;
225
- const data = this.editorTransfer.getData(DraggedEditorIdentifier.prototype);
226
- if (Array.isArray(data)) {
227
- const localDraggedEditor = data[0].identifier;
228
- if (this.groupView.id === localDraggedEditor.groupId && this.tabsModel.isLast(localDraggedEditor.editor)) {
229
- if (e.dataTransfer) {
230
- e.dataTransfer.dropEffect = 'none';
231
- }
232
- return;
233
- }
234
- }
235
- }
236
- if (!isLocalDragAndDrop) {
237
- if (e.dataTransfer) {
238
- e.dataTransfer.dropEffect = 'copy';
239
- }
240
- }
241
- this.updateDropFeedback(tabsContainer, true);
242
- },
243
- onDragLeave: e => {
244
- this.updateDropFeedback(tabsContainer, false);
245
- tabsContainer.classList.remove('scroll');
246
- },
247
- onDragEnd: e => {
248
- this.updateDropFeedback(tabsContainer, false);
249
- tabsContainer.classList.remove('scroll');
250
- this.onGroupDragEnd(e, lastDragEvent, tabsContainer);
251
- },
252
- onDrop: e => {
253
- this.updateDropFeedback(tabsContainer, false);
254
- tabsContainer.classList.remove('scroll');
255
- if (e.target === tabsContainer) {
256
- const isGroupTransfer = this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype);
257
- this.onDrop(e, isGroupTransfer ? this.groupView.count : this.tabsModel.count, tabsContainer);
258
- }
259
- }
260
- })));
261
- this._register(addDisposableListener(tabsContainer, EventType.MOUSE_WHEEL, (e) => {
262
- const activeEditor = this.groupView.activeEditor;
263
- if (!activeEditor || this.groupView.count < 2) {
264
- return;
265
- }
266
- if (this.groupsView.partOptions.scrollToSwitchTabs === true) {
267
- if (e.shiftKey) {
268
- return;
269
- }
270
- }
271
- else {
272
- if (!e.shiftKey) {
273
- return;
274
- }
275
- }
276
- const now = Date.now();
277
- if (now - this.lastMouseWheelEventTime < MultiEditorTabsControl_1.MOUSE_WHEEL_EVENT_THRESHOLD - 2 * (Math.abs(e.deltaX) + Math.abs(e.deltaY))) {
278
- return;
279
- }
280
- this.lastMouseWheelEventTime = now;
281
- let tabSwitchDirection;
282
- if (e.deltaX + e.deltaY < -MultiEditorTabsControl_1.MOUSE_WHEEL_DISTANCE_THRESHOLD) {
283
- tabSwitchDirection = -1;
284
- }
285
- else if (e.deltaX + e.deltaY > MultiEditorTabsControl_1.MOUSE_WHEEL_DISTANCE_THRESHOLD) {
286
- tabSwitchDirection = 1;
287
- }
288
- else {
289
- return;
290
- }
291
- const nextEditor = this.groupView.getEditorByIndex(this.groupView.getIndexOfEditor(activeEditor) + tabSwitchDirection);
292
- if (!nextEditor) {
293
- return;
294
- }
295
- this.groupView.openEditor(nextEditor);
296
- EventHelper.stop(e, true);
297
- }));
298
- const showContextMenu = (e) => {
299
- EventHelper.stop(e);
300
- let anchor = tabsContainer;
301
- if (isMouseEvent(e)) {
302
- anchor = ( new StandardMouseEvent(getWindow(this.parent), e));
303
- }
304
- this.contextMenuService.showContextMenu({
305
- getAnchor: () => anchor,
306
- menuId: MenuId.EditorTabsBarContext,
307
- contextKeyService: this.contextKeyService,
308
- menuActionOptions: { shouldForwardArgs: true },
309
- getActionsContext: () => ({ groupId: this.groupView.id }),
310
- getKeyBinding: action => this.getKeybinding(action),
311
- onHide: () => this.groupView.focus()
312
- });
313
- };
314
- this._register(addDisposableListener(tabsContainer, EventType$1.Contextmenu, e => showContextMenu(e)));
315
- this._register(addDisposableListener(tabsContainer, EventType.CONTEXT_MENU, e => showContextMenu(e)));
316
- }
317
- doHandleDecorationsChange() {
318
- this.layout(this.dimensions);
319
- }
320
- updateEditorActionsToolbar() {
321
- super.updateEditorActionsToolbar();
322
- this.layout(this.dimensions);
323
- }
324
- openEditor(editor, options) {
325
- const changed = this.handleOpenedEditors();
326
- if (options?.focusTabControl) {
327
- this.withTab(editor, (editor, tabIndex, tabContainer) => tabContainer.focus());
328
- }
329
- return changed;
330
- }
331
- openEditors(editors) {
332
- return this.handleOpenedEditors();
333
- }
334
- handleOpenedEditors() {
335
- this.updateTabsControlVisibility();
336
- const [tabsContainer, tabsScrollbar] = assertAllDefined(this.tabsContainer, this.tabsScrollbar);
337
- for (let i = tabsContainer.children.length; i < this.tabsModel.count; i++) {
338
- tabsContainer.appendChild(this.createTab(i, tabsContainer, tabsScrollbar));
339
- }
340
- const activeEditorChanged = this.didActiveEditorChange();
341
- const oldActiveTabLabel = this.activeTabLabel;
342
- const oldTabLabelsLength = this.tabLabels.length;
343
- this.computeTabLabels();
344
- let didChange = false;
345
- if (activeEditorChanged ||
346
- oldTabLabelsLength !== this.tabLabels.length ||
347
- !this.equalsEditorInputLabel(oldActiveTabLabel, this.activeTabLabel)
348
- ) {
349
- this.redraw({ forceRevealActiveTab: true });
350
- didChange = true;
351
- }
352
- else {
353
- this.layout(this.dimensions, { forceRevealActiveTab: true });
354
- }
355
- return didChange;
356
- }
357
- didActiveEditorChange() {
358
- if (!this.activeTabLabel?.editor && this.tabsModel.activeEditor ||
359
- this.activeTabLabel?.editor && !this.tabsModel.activeEditor ||
360
- (!this.activeTabLabel?.editor || !this.tabsModel.isActive(this.activeTabLabel.editor))
361
- ) {
362
- return true;
363
- }
364
- return false;
365
- }
366
- equalsEditorInputLabel(labelA, labelB) {
367
- if (labelA === labelB) {
368
- return true;
369
- }
370
- if (!labelA || !labelB) {
371
- return false;
372
- }
373
- return labelA.name === labelB.name &&
374
- labelA.description === labelB.description &&
375
- labelA.forceDescription === labelB.forceDescription &&
376
- labelA.title === labelB.title &&
377
- labelA.ariaLabel === labelB.ariaLabel;
378
- }
379
- beforeCloseEditor(editor) {
380
- if (this.isMouseOverTabs && this.groupsView.partOptions.tabSizing === 'fixed') {
381
- const closingLastTab = this.tabsModel.isLast(editor);
382
- this.updateTabsFixedWidth(!closingLastTab);
383
- }
384
- }
385
- closeEditor(editor) {
386
- this.handleClosedEditors();
387
- }
388
- closeEditors(editors) {
389
- this.handleClosedEditors();
390
- }
391
- handleClosedEditors() {
392
- if (this.tabsModel.count) {
393
- const tabsContainer = assertIsDefined(this.tabsContainer);
394
- while (tabsContainer.children.length > this.tabsModel.count) {
395
- tabsContainer.lastChild?.remove();
396
- dispose(this.tabDisposables.pop());
397
- }
398
- this.computeTabLabels();
399
- this.redraw({ forceRevealActiveTab: true });
400
- }
401
- else {
402
- if (this.tabsContainer) {
403
- clearNode(this.tabsContainer);
404
- }
405
- this.tabDisposables = dispose(this.tabDisposables);
406
- this.tabResourceLabels.clear();
407
- this.tabLabels = [];
408
- this.activeTabLabel = undefined;
409
- this.tabActionBars = [];
410
- this.clearEditorActionsToolbar();
411
- this.updateTabsControlVisibility();
412
- }
413
- }
414
- moveEditor(editor, fromTabIndex, targeTabIndex) {
415
- const editorLabel = this.tabLabels[fromTabIndex];
416
- this.tabLabels.splice(fromTabIndex, 1);
417
- this.tabLabels.splice(targeTabIndex, 0, editorLabel);
418
- this.forEachTab((editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) => {
419
- this.redrawTab(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar);
420
- }, Math.min(fromTabIndex, targeTabIndex),
421
- Math.max(fromTabIndex, targeTabIndex)
422
- );
423
- this.layout(this.dimensions, { forceRevealActiveTab: true });
424
- }
425
- pinEditor(editor) {
426
- this.withTab(editor, (editor, tabIndex, tabContainer, tabLabelWidget, tabLabel) => this.redrawTabLabel(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel));
427
- }
428
- stickEditor(editor) {
429
- this.doHandleStickyEditorChange(editor);
430
- }
431
- unstickEditor(editor) {
432
- this.doHandleStickyEditorChange(editor);
433
- }
434
- doHandleStickyEditorChange(editor) {
435
- this.withTab(editor, (editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) => this.redrawTab(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar));
436
- this.forEachTab((editor, tabIndex, tabContainer, tabLabelWidget, tabLabel) => {
437
- this.redrawTabBorders(tabIndex, tabContainer);
438
- });
439
- this.layout(this.dimensions, { forceRevealActiveTab: true });
440
- }
441
- setActive(isGroupActive) {
442
- this.forEachTab((editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) => {
443
- this.redrawTabActiveAndDirty(isGroupActive, editor, tabContainer, tabActionBar);
444
- });
445
- this.updateEditorActionsToolbar();
446
- this.layout(this.dimensions, { forceRevealActiveTab: true });
447
- }
448
- updateEditorLabel(editor) {
449
- this.updateEditorLabelScheduler.schedule();
450
- }
451
- doUpdateEditorLabels() {
452
- this.computeTabLabels();
453
- this.forEachTab((editor, tabIndex, tabContainer, tabLabelWidget, tabLabel) => {
454
- this.redrawTabLabel(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel);
455
- });
456
- this.layout(this.dimensions);
457
- }
458
- updateEditorDirty(editor) {
459
- this.withTab(editor, (editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) => this.redrawTabActiveAndDirty(this.groupsView.activeGroup === this.groupView, editor, tabContainer, tabActionBar));
460
- }
461
- updateOptions(oldOptions, newOptions) {
462
- super.updateOptions(oldOptions, newOptions);
463
- if (oldOptions.labelFormat !== newOptions.labelFormat) {
464
- this.computeTabLabels();
465
- }
466
- if (oldOptions.titleScrollbarSizing !== newOptions.titleScrollbarSizing) {
467
- this.updateTabsScrollbarSizing();
468
- }
469
- if (oldOptions.tabSizingFixedMinWidth !== newOptions.tabSizingFixedMinWidth ||
470
- oldOptions.tabSizingFixedMaxWidth !== newOptions.tabSizingFixedMaxWidth ||
471
- oldOptions.tabSizing !== newOptions.tabSizing) {
472
- this.updateTabSizing(true);
473
- }
474
- if (oldOptions.labelFormat !== newOptions.labelFormat ||
475
- oldOptions.tabActionLocation !== newOptions.tabActionLocation ||
476
- oldOptions.tabActionCloseVisibility !== newOptions.tabActionCloseVisibility ||
477
- oldOptions.tabActionUnpinVisibility !== newOptions.tabActionUnpinVisibility ||
478
- oldOptions.tabSizing !== newOptions.tabSizing ||
479
- oldOptions.pinnedTabSizing !== newOptions.pinnedTabSizing ||
480
- oldOptions.showIcons !== newOptions.showIcons ||
481
- oldOptions.hasIcons !== newOptions.hasIcons ||
482
- oldOptions.highlightModifiedTabs !== newOptions.highlightModifiedTabs ||
483
- oldOptions.wrapTabs !== newOptions.wrapTabs ||
484
- !equals(oldOptions.decorations, newOptions.decorations)) {
485
- this.redraw();
486
- }
487
- }
488
- updateStyles() {
489
- this.redraw();
490
- }
491
- forEachTab(fn, fromTabIndex, toTabIndex) {
492
- this.tabsModel.getEditors(1 ).forEach((editor, tabIndex) => {
493
- if (typeof fromTabIndex === 'number' && fromTabIndex > tabIndex) {
494
- return;
495
- }
496
- if (typeof toTabIndex === 'number' && toTabIndex < tabIndex) {
497
- return;
498
- }
499
- this.doWithTab(tabIndex, editor, fn);
500
- });
501
- }
502
- withTab(editor, fn) {
503
- this.doWithTab(this.tabsModel.indexOf(editor), editor, fn);
504
- }
505
- doWithTab(tabIndex, editor, fn) {
506
- const tabsContainer = assertIsDefined(this.tabsContainer);
507
- const tabContainer = tabsContainer.children[tabIndex];
508
- const tabResourceLabel = this.tabResourceLabels.get(tabIndex);
509
- const tabLabel = this.tabLabels[tabIndex];
510
- const tabActionBar = this.tabActionBars[tabIndex];
511
- if (tabContainer && tabResourceLabel && tabLabel) {
512
- fn(editor, tabIndex, tabContainer, tabResourceLabel, tabLabel, tabActionBar);
513
- }
514
- }
515
- createTab(tabIndex, tabsContainer, tabsScrollbar) {
516
- const tabContainer = document.createElement('div');
517
- tabContainer.draggable = true;
518
- tabContainer.setAttribute('role', 'tab');
519
- tabContainer.classList.add('tab');
520
- this._register(Gesture.addTarget(tabContainer));
521
- const tabBorderTopContainer = document.createElement('div');
522
- tabBorderTopContainer.classList.add('tab-border-top-container');
523
- tabContainer.appendChild(tabBorderTopContainer);
524
- const editorLabel = this.tabResourceLabels.create(tabContainer);
525
- const tabActionsContainer = document.createElement('div');
526
- tabActionsContainer.classList.add('tab-actions');
527
- tabContainer.appendChild(tabActionsContainer);
528
- const that = this;
529
- const tabActionRunner = ( new EditorCommandsContextActionRunner({
530
- groupId: this.groupView.id,
531
- get editorIndex() { return that.toEditorIndex(tabIndex); }
532
- }));
533
- const tabActionBar = ( new ActionBar(tabActionsContainer, { ariaLabel: ( localizeWithPath(
534
- 'vs/workbench/browser/parts/editor/multiEditorTabsControl',
535
- 'ariaLabelTabActions',
536
- "Tab actions"
537
- )), actionRunner: tabActionRunner }));
538
- const tabActionListener = tabActionBar.onWillRun(e => {
539
- if (e.action.id === this.closeEditorAction.id) {
540
- this.blockRevealActiveTabOnce();
541
- }
542
- });
543
- const tabActionBarDisposable = combinedDisposable(tabActionBar, tabActionListener, toDisposable(insert(this.tabActionBars, tabActionBar)));
544
- const tabBorderBottomContainer = document.createElement('div');
545
- tabBorderBottomContainer.classList.add('tab-border-bottom-container');
546
- tabContainer.appendChild(tabBorderBottomContainer);
547
- const eventsDisposable = this.registerTabListeners(tabContainer, tabIndex, tabsContainer, tabsScrollbar);
548
- this.tabDisposables.push(combinedDisposable(eventsDisposable, tabActionBarDisposable, tabActionRunner, editorLabel));
549
- return tabContainer;
550
- }
551
- toEditorIndex(tabIndex) {
552
- const editor = assertIsDefined(this.tabsModel.getEditorByIndex(tabIndex));
553
- return this.groupView.getIndexOfEditor(editor);
554
- }
555
- registerTabListeners(tab, tabIndex, tabsContainer, tabsScrollbar) {
556
- const disposables = ( new DisposableStore());
557
- const handleClickOrTouch = (e, preserveFocus) => {
558
- tab.blur();
559
- if (isMouseEvent(e) && (e.button !== 0 || ((isMacintosh && e.ctrlKey) ))) {
560
- if (e.button === 1) {
561
- e.preventDefault();
562
- }
563
- return undefined;
564
- }
565
- if (this.originatesFromTabActionBar(e)) {
566
- return;
567
- }
568
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
569
- if (editor) {
570
- this.groupView.openEditor(editor, { preserveFocus, activation: EditorActivation.ACTIVATE });
571
- }
572
- return undefined;
573
- };
574
- const showContextMenu = (e) => {
575
- EventHelper.stop(e);
576
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
577
- if (editor) {
578
- this.onTabContextMenu(editor, e, tab);
579
- }
580
- };
581
- disposables.add(addDisposableListener(tab, EventType.MOUSE_DOWN, e => handleClickOrTouch(e, false)));
582
- disposables.add(addDisposableListener(tab, EventType$1.Tap, (e) => handleClickOrTouch(e, true)));
583
- disposables.add(addDisposableListener(tab, EventType$1.Change, (e) => {
584
- tabsScrollbar.setScrollPosition({ scrollLeft: tabsScrollbar.getScrollPosition().scrollLeft - e.translationX });
585
- }));
586
- disposables.add(addDisposableListener(tab, EventType.MOUSE_UP, e => {
587
- EventHelper.stop(e);
588
- tab.blur();
589
- }));
590
- disposables.add(addDisposableListener(tab, EventType.AUXCLICK, e => {
591
- if (e.button === 1 ) {
592
- EventHelper.stop(e, true );
593
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
594
- if (editor) {
595
- if (preventEditorClose(this.tabsModel, editor, EditorCloseMethod.MOUSE, this.groupsView.partOptions)) {
596
- return;
597
- }
598
- this.blockRevealActiveTabOnce();
599
- this.closeEditorAction.run({ groupId: this.groupView.id, editorIndex: this.groupView.getIndexOfEditor(editor) });
600
- }
601
- }
602
- }));
603
- disposables.add(addDisposableListener(tab, EventType.KEY_DOWN, e => {
604
- const event = ( new StandardKeyboardEvent(e));
605
- if (event.shiftKey && event.keyCode === 68 ) {
606
- showContextMenu(e);
607
- }
608
- }));
609
- disposables.add(addDisposableListener(tab, EventType$1.Contextmenu, (e) => {
610
- showContextMenu(e);
611
- }));
612
- disposables.add(addDisposableListener(tab, EventType.KEY_UP, e => {
613
- const event = ( new StandardKeyboardEvent(e));
614
- let handled = false;
615
- if (event.equals(3 ) || event.equals(10 )) {
616
- handled = true;
617
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
618
- if (editor) {
619
- this.groupView.openEditor(editor);
620
- }
621
- }
622
- else if (( [15 , 17 , 16 , 18 , 14 , 13 ].some(kb => event.equals(kb)))) {
623
- let editorIndex = this.toEditorIndex(tabIndex);
624
- if (event.equals(15 ) || event.equals(16 )) {
625
- editorIndex = editorIndex - 1;
626
- }
627
- else if (event.equals(17 ) || event.equals(18 )) {
628
- editorIndex = editorIndex + 1;
629
- }
630
- else if (event.equals(14 )) {
631
- editorIndex = 0;
632
- }
633
- else {
634
- editorIndex = this.groupView.count - 1;
635
- }
636
- const target = this.groupView.getEditorByIndex(editorIndex);
637
- if (target) {
638
- handled = true;
639
- this.groupView.openEditor(target, { preserveFocus: true }, { focusTabControl: true });
640
- }
641
- }
642
- if (handled) {
643
- EventHelper.stop(e, true);
644
- }
645
- tabsScrollbar.setScrollPosition({
646
- scrollLeft: tabsContainer.scrollLeft
647
- });
648
- }));
649
- for (const eventType of [EventType$1.Tap, EventType.DBLCLICK]) {
650
- disposables.add(addDisposableListener(tab, eventType, (e) => {
651
- if (eventType === EventType.DBLCLICK) {
652
- EventHelper.stop(e);
653
- }
654
- else if (e.tapCount !== 2) {
655
- return;
656
- }
657
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
658
- if (editor && this.tabsModel.isPinned(editor)) {
659
- switch (this.groupsView.partOptions.doubleClickTabToToggleEditorGroupSizes) {
660
- case 'maximize':
661
- this.groupsView.toggleMaximizeGroup(this.groupView);
662
- break;
663
- case 'expand':
664
- this.groupsView.toggleExpandGroup(this.groupView);
665
- break;
666
- }
667
- }
668
- else {
669
- this.groupView.pinEditor(editor);
670
- }
671
- }));
672
- }
673
- disposables.add(addDisposableListener(tab, EventType.CONTEXT_MENU, e => {
674
- EventHelper.stop(e, true);
675
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
676
- if (editor) {
677
- this.onTabContextMenu(editor, e, tab);
678
- }
679
- }, true ));
680
- let lastDragEvent = undefined;
681
- disposables.add(( new DragAndDropObserver(tab, {
682
- onDragStart: e => {
683
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
684
- if (!editor) {
685
- return;
686
- }
687
- this.editorTransfer.setData([( new DraggedEditorIdentifier({ editor, groupId: this.groupView.id }))], DraggedEditorIdentifier.prototype);
688
- if (e.dataTransfer) {
689
- e.dataTransfer.effectAllowed = 'copyMove';
690
- }
691
- this.doFillResourceDataTransfers([editor], e);
692
- tab.classList.add('dragged');
693
- scheduleAtNextAnimationFrame(getWindow(this.parent), () => tab.classList.remove('dragged'));
694
- },
695
- onDrag: e => {
696
- lastDragEvent = e;
697
- },
698
- onDragEnter: e => {
699
- tab.classList.add('dragged-over');
700
- if (!this.isSupportedDropTransfer(e)) {
701
- if (e.dataTransfer) {
702
- e.dataTransfer.dropEffect = 'none';
703
- }
704
- return;
705
- }
706
- let isLocalDragAndDrop = false;
707
- if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) {
708
- isLocalDragAndDrop = true;
709
- const data = this.editorTransfer.getData(DraggedEditorIdentifier.prototype);
710
- if (Array.isArray(data)) {
711
- const localDraggedEditor = data[0].identifier;
712
- if (localDraggedEditor.editor === this.tabsModel.getEditorByIndex(tabIndex) && localDraggedEditor.groupId === this.groupView.id) {
713
- if (e.dataTransfer) {
714
- e.dataTransfer.dropEffect = 'none';
715
- }
716
- return;
717
- }
718
- }
719
- }
720
- if (!isLocalDragAndDrop) {
721
- if (e.dataTransfer) {
722
- e.dataTransfer.dropEffect = 'copy';
723
- }
724
- }
725
- this.updateDropFeedback(tab, true, tabIndex);
726
- },
727
- onDragOver: (_, dragDuration) => {
728
- if (dragDuration >= MultiEditorTabsControl_1.DRAG_OVER_OPEN_TAB_THRESHOLD) {
729
- const draggedOverTab = this.tabsModel.getEditorByIndex(tabIndex);
730
- if (draggedOverTab && this.tabsModel.activeEditor !== draggedOverTab) {
731
- this.groupView.openEditor(draggedOverTab, { preserveFocus: true });
732
- }
733
- }
734
- },
735
- onDragLeave: () => {
736
- tab.classList.remove('dragged-over');
737
- this.updateDropFeedback(tab, false, tabIndex);
738
- },
739
- onDragEnd: async (e) => {
740
- tab.classList.remove('dragged-over');
741
- this.updateDropFeedback(tab, false, tabIndex);
742
- this.editorTransfer.clearData(DraggedEditorIdentifier.prototype);
743
- const editor = this.tabsModel.getEditorByIndex(tabIndex);
744
- if (!this.isNewWindowOperation(lastDragEvent ?? e) ||
745
- isWindowDraggedOver() ||
746
- !editor) {
747
- return;
748
- }
749
- const auxiliaryEditorPart = await this.maybeCreateAuxiliaryEditorPartAt(e, tab);
750
- if (!auxiliaryEditorPart) {
751
- return;
752
- }
753
- const targetGroup = auxiliaryEditorPart.activeGroup;
754
- if (this.isMoveOperation(lastDragEvent ?? e, targetGroup.id, editor)) {
755
- this.groupView.moveEditor(editor, targetGroup);
756
- }
757
- else {
758
- this.groupView.copyEditor(editor, targetGroup);
759
- }
760
- targetGroup.focus();
761
- },
762
- onDrop: e => {
763
- tab.classList.remove('dragged-over');
764
- this.updateDropFeedback(tab, false, tabIndex);
765
- this.onDrop(e, tabIndex, tabsContainer);
766
- }
767
- })));
768
- return disposables;
769
- }
770
- isSupportedDropTransfer(e) {
771
- if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) {
772
- const data = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype);
773
- if (Array.isArray(data)) {
774
- const group = data[0];
775
- if (group.identifier === this.groupView.id) {
776
- return false;
777
- }
778
- }
779
- return true;
780
- }
781
- if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) {
782
- return true;
783
- }
784
- if (e.dataTransfer && e.dataTransfer.types.length > 0) {
785
- return true;
786
- }
787
- return false;
788
- }
789
- updateDropFeedback(element, isDND, tabIndex) {
790
- const isTab = (typeof tabIndex === 'number');
791
- const editor = typeof tabIndex === 'number' ? this.tabsModel.getEditorByIndex(tabIndex) : undefined;
792
- const isActiveTab = isTab && !!editor && this.tabsModel.isActive(editor);
793
- const noDNDBackgroundColor = isTab ? this.getColor(isActiveTab ? TAB_ACTIVE_BACKGROUND : TAB_INACTIVE_BACKGROUND) : '';
794
- element.style.backgroundColor = (isDND ? this.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND) : noDNDBackgroundColor) || '';
795
- const activeContrastBorderColor = this.getColor(activeContrastBorder);
796
- if (activeContrastBorderColor && isDND) {
797
- element.style.outlineWidth = '2px';
798
- element.style.outlineStyle = 'dashed';
799
- element.style.outlineColor = activeContrastBorderColor;
800
- element.style.outlineOffset = isTab ? '-5px' : '-3px';
801
- }
802
- else {
803
- element.style.outlineWidth = '';
804
- element.style.outlineStyle = '';
805
- element.style.outlineColor = activeContrastBorderColor || '';
806
- element.style.outlineOffset = '';
807
- }
808
- }
809
- computeTabLabels() {
810
- const { labelFormat } = this.groupsView.partOptions;
811
- const { verbosity, shortenDuplicates } = this.getLabelConfigFlags(labelFormat);
812
- const labels = [];
813
- let activeEditorTabIndex = -1;
814
- this.tabsModel.getEditors(1 ).forEach((editor, tabIndex) => {
815
- labels.push({
816
- editor,
817
- name: editor.getName(),
818
- description: editor.getDescription(verbosity),
819
- forceDescription: editor.hasCapability(64 ),
820
- title: editor.getTitle(2 ),
821
- ariaLabel: computeEditorAriaLabel(editor, tabIndex, this.groupView, this.editorPartsView.count)
822
- });
823
- if (editor === this.tabsModel.activeEditor) {
824
- activeEditorTabIndex = tabIndex;
825
- }
826
- });
827
- if (shortenDuplicates) {
828
- this.shortenTabLabels(labels);
829
- }
830
- this.tabLabels = labels;
831
- this.activeTabLabel = labels[activeEditorTabIndex];
832
- }
833
- shortenTabLabels(labels) {
834
- const mapNameToDuplicates = ( new Map());
835
- for (const label of labels) {
836
- if (typeof label.description === 'string') {
837
- getOrSet(mapNameToDuplicates, label.name, []).push(label);
838
- }
839
- else {
840
- label.description = '';
841
- }
842
- }
843
- for (const [, duplicateLabels] of mapNameToDuplicates) {
844
- if (duplicateLabels.length === 1 && !duplicateLabels[0].forceDescription) {
845
- duplicateLabels[0].description = '';
846
- continue;
847
- }
848
- const mapDescriptionToDuplicates = ( new Map());
849
- for (const duplicateLabel of duplicateLabels) {
850
- getOrSet(mapDescriptionToDuplicates, duplicateLabel.description, []).push(duplicateLabel);
851
- }
852
- let useLongDescriptions = false;
853
- for (const [, duplicateLabels] of mapDescriptionToDuplicates) {
854
- if (!useLongDescriptions && duplicateLabels.length > 1) {
855
- const [first, ...rest] = ( duplicateLabels.map(({ editor }) => editor.getDescription(2 )));
856
- useLongDescriptions = ( rest.some(description => description !== first));
857
- }
858
- }
859
- if (useLongDescriptions) {
860
- mapDescriptionToDuplicates.clear();
861
- for (const duplicateLabel of duplicateLabels) {
862
- duplicateLabel.description = duplicateLabel.editor.getDescription(2 );
863
- getOrSet(mapDescriptionToDuplicates, duplicateLabel.description, []).push(duplicateLabel);
864
- }
865
- }
866
- const descriptions = [];
867
- for (const [description] of mapDescriptionToDuplicates) {
868
- descriptions.push(description);
869
- }
870
- if (descriptions.length === 1) {
871
- for (const label of mapDescriptionToDuplicates.get(descriptions[0]) || []) {
872
- if (!label.forceDescription) {
873
- label.description = '';
874
- }
875
- }
876
- continue;
877
- }
878
- const shortenedDescriptions = shorten(descriptions, this.path.sep);
879
- descriptions.forEach((description, tabIndex) => {
880
- for (const label of mapDescriptionToDuplicates.get(description) || []) {
881
- label.description = shortenedDescriptions[tabIndex];
882
- }
883
- });
884
- }
885
- }
886
- getLabelConfigFlags(value) {
887
- switch (value) {
888
- case 'short':
889
- return { verbosity: 0 , shortenDuplicates: false };
890
- case 'medium':
891
- return { verbosity: 1 , shortenDuplicates: false };
892
- case 'long':
893
- return { verbosity: 2 , shortenDuplicates: false };
894
- default:
895
- return { verbosity: 1 , shortenDuplicates: true };
896
- }
897
- }
898
- redraw(options) {
899
- if (this.tabsAndActionsContainer) {
900
- let tabsContainerBorderColor = this.getColor(EDITOR_GROUP_HEADER_TABS_BORDER);
901
- if (!tabsContainerBorderColor && isHighContrast(this.theme.type)) {
902
- tabsContainerBorderColor = this.getColor(TAB_BORDER) || this.getColor(contrastBorder);
903
- }
904
- if (tabsContainerBorderColor) {
905
- this.tabsAndActionsContainer.classList.add('tabs-border-bottom');
906
- this.tabsAndActionsContainer.style.setProperty('--tabs-border-bottom-color', ( tabsContainerBorderColor.toString()));
907
- }
908
- else {
909
- this.tabsAndActionsContainer.classList.remove('tabs-border-bottom');
910
- this.tabsAndActionsContainer.style.removeProperty('--tabs-border-bottom-color');
911
- }
912
- }
913
- this.forEachTab((editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) => {
914
- this.redrawTab(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar);
915
- });
916
- this.updateEditorActionsToolbar();
917
- this.layout(this.dimensions, options);
918
- }
919
- redrawTab(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel, tabActionBar) {
920
- const isTabSticky = this.tabsModel.isSticky(tabIndex);
921
- const options = this.groupsView.partOptions;
922
- this.redrawTabLabel(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel);
923
- const hasUnpinAction = isTabSticky && options.tabActionUnpinVisibility;
924
- const hasCloseAction = !hasUnpinAction && options.tabActionCloseVisibility;
925
- const hasAction = hasUnpinAction || hasCloseAction;
926
- let tabAction;
927
- if (hasAction) {
928
- tabAction = hasUnpinAction ? this.unpinEditorAction : this.closeEditorAction;
929
- }
930
- else {
931
- tabAction = isTabSticky ? this.unpinEditorAction : this.closeEditorAction;
932
- }
933
- if (!tabActionBar.hasAction(tabAction)) {
934
- if (!tabActionBar.isEmpty()) {
935
- tabActionBar.clear();
936
- }
937
- tabActionBar.push(tabAction, { icon: true, label: false, keybinding: this.getKeybindingLabel(tabAction) });
938
- }
939
- tabContainer.classList.toggle(`pinned-action-off`, isTabSticky && !hasUnpinAction);
940
- tabContainer.classList.toggle(`close-action-off`, !hasUnpinAction && !hasCloseAction);
941
- for (const option of ['left', 'right']) {
942
- tabContainer.classList.toggle(`tab-actions-${option}`, hasAction && options.tabActionLocation === option);
943
- }
944
- const tabSizing = isTabSticky && options.pinnedTabSizing === 'shrink' ? 'shrink' : options.tabSizing;
945
- for (const option of ['fit', 'shrink', 'fixed']) {
946
- tabContainer.classList.toggle(`sizing-${option}`, tabSizing === option);
947
- }
948
- tabContainer.classList.toggle('has-icon', options.showIcons && options.hasIcons);
949
- tabContainer.classList.toggle('sticky', isTabSticky);
950
- for (const option of ['normal', 'compact', 'shrink']) {
951
- tabContainer.classList.toggle(`sticky-${option}`, isTabSticky && options.pinnedTabSizing === option);
952
- }
953
- if (!options.wrapTabs && isTabSticky && options.pinnedTabSizing !== 'normal') {
954
- let stickyTabWidth = 0;
955
- switch (options.pinnedTabSizing) {
956
- case 'compact':
957
- stickyTabWidth = MultiEditorTabsControl_1.TAB_WIDTH.compact;
958
- break;
959
- case 'shrink':
960
- stickyTabWidth = MultiEditorTabsControl_1.TAB_WIDTH.shrink;
961
- break;
962
- }
963
- tabContainer.style.left = `${tabIndex * stickyTabWidth}px`;
964
- }
965
- else {
966
- tabContainer.style.left = 'auto';
967
- }
968
- this.redrawTabBorders(tabIndex, tabContainer);
969
- this.redrawTabActiveAndDirty(this.groupsView.activeGroup === this.groupView, editor, tabContainer, tabActionBar);
970
- }
971
- redrawTabLabel(editor, tabIndex, tabContainer, tabLabelWidget, tabLabel) {
972
- const options = this.groupsView.partOptions;
973
- let name;
974
- let forceLabel = false;
975
- let fileDecorationBadges = Boolean(options.decorations?.badges);
976
- const fileDecorationColors = Boolean(options.decorations?.colors);
977
- let description;
978
- if (options.pinnedTabSizing === 'compact' && this.tabsModel.isSticky(tabIndex)) {
979
- const isShowingIcons = options.showIcons && options.hasIcons;
980
- name = isShowingIcons ? '' : tabLabel.name?.charAt(0).toUpperCase();
981
- description = '';
982
- forceLabel = true;
983
- fileDecorationBadges = false;
984
- }
985
- else {
986
- name = tabLabel.name;
987
- description = tabLabel.description || '';
988
- }
989
- if (tabLabel.ariaLabel) {
990
- tabContainer.setAttribute('aria-label', tabLabel.ariaLabel);
991
- tabContainer.setAttribute('aria-description', '');
992
- }
993
- const title = tabLabel.title || '';
994
- tabContainer.title = title;
995
- tabLabelWidget.setResource({ name, description, resource: EditorResourceAccessor.getOriginalUri(editor, { supportSideBySide: SideBySideEditor.BOTH }) }, {
996
- title,
997
- extraClasses: coalesce(['tab-label', fileDecorationBadges ? 'tab-label-has-badge' : undefined].concat(editor.getLabelExtraClasses())),
998
- italic: !this.tabsModel.isPinned(editor),
999
- forceLabel,
1000
- fileDecorations: {
1001
- colors: fileDecorationColors,
1002
- badges: fileDecorationBadges
1003
- }
1004
- });
1005
- const resource = EditorResourceAccessor.getOriginalUri(editor, { supportSideBySide: SideBySideEditor.PRIMARY });
1006
- if (resource) {
1007
- tabContainer.setAttribute('data-resource-name', basenameOrAuthority(resource));
1008
- }
1009
- else {
1010
- tabContainer.removeAttribute('data-resource-name');
1011
- }
1012
- }
1013
- redrawTabActiveAndDirty(isGroupActive, editor, tabContainer, tabActionBar) {
1014
- const isTabActive = this.tabsModel.isActive(editor);
1015
- const hasModifiedBorderTop = this.doRedrawTabDirty(isGroupActive, isTabActive, editor, tabContainer);
1016
- this.doRedrawTabActive(isGroupActive, !hasModifiedBorderTop, editor, tabContainer, tabActionBar);
1017
- }
1018
- doRedrawTabActive(isGroupActive, allowBorderTop, editor, tabContainer, tabActionBar) {
1019
- if (this.tabsModel.isActive(editor)) {
1020
- tabContainer.classList.add('active');
1021
- tabContainer.setAttribute('aria-selected', 'true');
1022
- tabContainer.tabIndex = 0;
1023
- tabContainer.style.backgroundColor = this.getColor(isGroupActive ? TAB_ACTIVE_BACKGROUND : TAB_UNFOCUSED_ACTIVE_BACKGROUND) || '';
1024
- const activeTabBorderColorBottom = this.getColor(isGroupActive ? TAB_ACTIVE_BORDER : TAB_UNFOCUSED_ACTIVE_BORDER);
1025
- if (activeTabBorderColorBottom) {
1026
- tabContainer.classList.add('tab-border-bottom');
1027
- tabContainer.style.setProperty('--tab-border-bottom-color', ( activeTabBorderColorBottom.toString()));
1028
- }
1029
- else {
1030
- tabContainer.classList.remove('tab-border-bottom');
1031
- tabContainer.style.removeProperty('--tab-border-bottom-color');
1032
- }
1033
- const activeTabBorderColorTop = allowBorderTop ? this.getColor(isGroupActive ? TAB_ACTIVE_BORDER_TOP : TAB_UNFOCUSED_ACTIVE_BORDER_TOP) : undefined;
1034
- if (activeTabBorderColorTop) {
1035
- tabContainer.classList.add('tab-border-top');
1036
- tabContainer.style.setProperty('--tab-border-top-color', ( activeTabBorderColorTop.toString()));
1037
- }
1038
- else {
1039
- tabContainer.classList.remove('tab-border-top');
1040
- tabContainer.style.removeProperty('--tab-border-top-color');
1041
- }
1042
- tabContainer.style.color = this.getColor(isGroupActive ? TAB_ACTIVE_FOREGROUND : TAB_UNFOCUSED_ACTIVE_FOREGROUND) || '';
1043
- tabActionBar.setFocusable(true);
1044
- }
1045
- else {
1046
- tabContainer.classList.remove('active');
1047
- tabContainer.setAttribute('aria-selected', 'false');
1048
- tabContainer.tabIndex = -1;
1049
- tabContainer.style.backgroundColor = this.getColor(isGroupActive ? TAB_INACTIVE_BACKGROUND : TAB_UNFOCUSED_INACTIVE_BACKGROUND) || '';
1050
- tabContainer.style.boxShadow = '';
1051
- tabContainer.style.color = this.getColor(isGroupActive ? TAB_INACTIVE_FOREGROUND : TAB_UNFOCUSED_INACTIVE_FOREGROUND) || '';
1052
- tabActionBar.setFocusable(false);
1053
- }
1054
- }
1055
- doRedrawTabDirty(isGroupActive, isTabActive, editor, tabContainer) {
1056
- let hasModifiedBorderColor = false;
1057
- if (editor.isDirty() && !editor.isSaving()) {
1058
- tabContainer.classList.add('dirty');
1059
- if (this.groupsView.partOptions.highlightModifiedTabs) {
1060
- let modifiedBorderColor;
1061
- if (isGroupActive && isTabActive) {
1062
- modifiedBorderColor = this.getColor(TAB_ACTIVE_MODIFIED_BORDER);
1063
- }
1064
- else if (isGroupActive && !isTabActive) {
1065
- modifiedBorderColor = this.getColor(TAB_INACTIVE_MODIFIED_BORDER);
1066
- }
1067
- else if (!isGroupActive && isTabActive) {
1068
- modifiedBorderColor = this.getColor(TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER);
1069
- }
1070
- else {
1071
- modifiedBorderColor = this.getColor(TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER);
1072
- }
1073
- if (modifiedBorderColor) {
1074
- hasModifiedBorderColor = true;
1075
- tabContainer.classList.add('dirty-border-top');
1076
- tabContainer.style.setProperty('--tab-dirty-border-top-color', modifiedBorderColor);
1077
- }
1078
- }
1079
- else {
1080
- tabContainer.classList.remove('dirty-border-top');
1081
- tabContainer.style.removeProperty('--tab-dirty-border-top-color');
1082
- }
1083
- }
1084
- else {
1085
- tabContainer.classList.remove('dirty', 'dirty-border-top');
1086
- tabContainer.style.removeProperty('--tab-dirty-border-top-color');
1087
- }
1088
- return hasModifiedBorderColor;
1089
- }
1090
- redrawTabBorders(tabIndex, tabContainer) {
1091
- const isTabSticky = this.tabsModel.isSticky(tabIndex);
1092
- const isTabLastSticky = isTabSticky && this.tabsModel.stickyCount === tabIndex + 1;
1093
- const showLastStickyTabBorderColor = this.tabsModel.stickyCount !== this.tabsModel.count;
1094
- const borderRightColor = ((isTabLastSticky && showLastStickyTabBorderColor ? this.getColor(TAB_LAST_PINNED_BORDER) : undefined) || this.getColor(TAB_BORDER) || this.getColor(contrastBorder));
1095
- tabContainer.style.borderRight = borderRightColor ? `1px solid ${borderRightColor}` : '';
1096
- tabContainer.style.outlineColor = this.getColor(activeContrastBorder) || '';
1097
- }
1098
- prepareEditorActions(editorActions) {
1099
- const isGroupActive = this.groupsView.activeGroup === this.groupView;
1100
- if (isGroupActive) {
1101
- return editorActions;
1102
- }
1103
- else {
1104
- return {
1105
- primary: editorActions.primary.filter(action => action.id === UNLOCK_GROUP_COMMAND_ID),
1106
- secondary: editorActions.secondary
1107
- };
1108
- }
1109
- }
1110
- getHeight() {
1111
- if (this.dimensions.used) {
1112
- return this.dimensions.used.height;
1113
- }
1114
- else {
1115
- return this.computeHeight();
1116
- }
1117
- }
1118
- computeHeight() {
1119
- let height;
1120
- if (!this.visible) {
1121
- height = 0;
1122
- }
1123
- else if (this.groupsView.partOptions.wrapTabs && this.tabsAndActionsContainer?.classList.contains('wrapping')) {
1124
- height = this.tabsAndActionsContainer.offsetHeight;
1125
- }
1126
- else {
1127
- height = this.tabHeight;
1128
- }
1129
- return height;
1130
- }
1131
- layout(dimensions, options) {
1132
- Object.assign(this.dimensions, dimensions);
1133
- if (this.visible) {
1134
- if (!this.layoutScheduler.value) {
1135
- const disposable = scheduleAtNextAnimationFrame(getWindow(this.parent), () => {
1136
- this.doLayout(this.dimensions, this.layoutScheduler.value?.options );
1137
- this.layoutScheduler.clear();
1138
- });
1139
- this.layoutScheduler.value = { options, dispose: () => disposable.dispose() };
1140
- }
1141
- if (options?.forceRevealActiveTab) {
1142
- this.layoutScheduler.value.options = {
1143
- ...this.layoutScheduler.value.options,
1144
- forceRevealActiveTab: true
1145
- };
1146
- }
1147
- }
1148
- if (!this.dimensions.used) {
1149
- this.dimensions.used = ( new Dimension(dimensions.container.width, this.computeHeight()));
1150
- }
1151
- return this.dimensions.used;
1152
- }
1153
- doLayout(dimensions, options) {
1154
- if (dimensions.container !== Dimension.None && dimensions.available !== Dimension.None) {
1155
- this.doLayoutTabs(dimensions, options);
1156
- }
1157
- const oldDimension = this.dimensions.used;
1158
- const newDimension = this.dimensions.used = ( new Dimension(dimensions.container.width, this.computeHeight()));
1159
- if (oldDimension && oldDimension.height !== newDimension.height) {
1160
- this.groupView.relayout();
1161
- }
1162
- }
1163
- doLayoutTabs(dimensions, options) {
1164
- const tabsWrapMultiLine = this.doLayoutTabsWrapping(dimensions);
1165
- if (!tabsWrapMultiLine) {
1166
- this.doLayoutTabsNonWrapping(options);
1167
- }
1168
- }
1169
- doLayoutTabsWrapping(dimensions) {
1170
- const [tabsAndActionsContainer, tabsContainer, editorToolbarContainer, tabsScrollbar] = assertAllDefined(this.tabsAndActionsContainer, this.tabsContainer, this.editorActionsToolbarContainer, this.tabsScrollbar);
1171
- const didTabsWrapMultiLine = tabsAndActionsContainer.classList.contains('wrapping');
1172
- let tabsWrapMultiLine = didTabsWrapMultiLine;
1173
- function updateTabsWrapping(enabled) {
1174
- tabsWrapMultiLine = enabled;
1175
- tabsAndActionsContainer.classList.toggle('wrapping', tabsWrapMultiLine);
1176
- tabsContainer.style.setProperty('--last-tab-margin-right', tabsWrapMultiLine ? `${editorToolbarContainer.offsetWidth}px` : '0');
1177
- }
1178
- if (this.groupsView.partOptions.wrapTabs) {
1179
- const visibleTabsWidth = tabsContainer.offsetWidth;
1180
- const allTabsWidth = tabsContainer.scrollWidth;
1181
- const lastTabFitsWrapped = () => {
1182
- const lastTab = this.getLastTab();
1183
- if (!lastTab) {
1184
- return true;
1185
- }
1186
- const lastTabOverlapWithToolbarWidth = lastTab.offsetWidth + editorToolbarContainer.offsetWidth - dimensions.available.width;
1187
- if (lastTabOverlapWithToolbarWidth > 1) {
1188
- return false;
1189
- }
1190
- return true;
1191
- };
1192
- if (tabsWrapMultiLine || (allTabsWidth > visibleTabsWidth && lastTabFitsWrapped())) {
1193
- updateTabsWrapping(true);
1194
- }
1195
- if (tabsWrapMultiLine) {
1196
- if ((tabsContainer.offsetHeight > dimensions.available.height) ||
1197
- (allTabsWidth === visibleTabsWidth && tabsContainer.offsetHeight === this.tabHeight) ||
1198
- (!lastTabFitsWrapped())
1199
- ) {
1200
- updateTabsWrapping(false);
1201
- }
1202
- }
1203
- }
1204
- else if (didTabsWrapMultiLine) {
1205
- updateTabsWrapping(false);
1206
- }
1207
- if (tabsWrapMultiLine && !didTabsWrapMultiLine) {
1208
- const visibleTabsWidth = tabsContainer.offsetWidth;
1209
- tabsScrollbar.setScrollDimensions({
1210
- width: visibleTabsWidth,
1211
- scrollWidth: visibleTabsWidth
1212
- });
1213
- }
1214
- if (tabsWrapMultiLine) {
1215
- const tabs = ( new Map());
1216
- let currentTabsPosY = undefined;
1217
- let lastTab = undefined;
1218
- for (const child of tabsContainer.children) {
1219
- const tab = child;
1220
- const tabPosY = tab.offsetTop;
1221
- if (tabPosY !== currentTabsPosY) {
1222
- currentTabsPosY = tabPosY;
1223
- if (lastTab) {
1224
- tabs.set(lastTab, true);
1225
- }
1226
- }
1227
- lastTab = tab;
1228
- tabs.set(tab, false);
1229
- }
1230
- if (lastTab) {
1231
- tabs.set(lastTab, true);
1232
- }
1233
- for (const [tab, lastInRow] of tabs) {
1234
- tab.classList.toggle('last-in-row', lastInRow);
1235
- }
1236
- }
1237
- return tabsWrapMultiLine;
1238
- }
1239
- doLayoutTabsNonWrapping(options) {
1240
- const [tabsContainer, tabsScrollbar] = assertAllDefined(this.tabsContainer, this.tabsScrollbar);
1241
- const visibleTabsWidth = tabsContainer.offsetWidth;
1242
- const allTabsWidth = tabsContainer.scrollWidth;
1243
- let stickyTabsWidth = 0;
1244
- if (this.tabsModel.stickyCount > 0) {
1245
- let stickyTabWidth = 0;
1246
- switch (this.groupsView.partOptions.pinnedTabSizing) {
1247
- case 'compact':
1248
- stickyTabWidth = MultiEditorTabsControl_1.TAB_WIDTH.compact;
1249
- break;
1250
- case 'shrink':
1251
- stickyTabWidth = MultiEditorTabsControl_1.TAB_WIDTH.shrink;
1252
- break;
1253
- }
1254
- stickyTabsWidth = this.tabsModel.stickyCount * stickyTabWidth;
1255
- }
1256
- const activeTabAndIndex = this.tabsModel.activeEditor ? this.getTabAndIndex(this.tabsModel.activeEditor) : undefined;
1257
- const [activeTab, activeTabIndex] = activeTabAndIndex ?? [undefined, undefined];
1258
- let activeTabPositionStatic = this.groupsView.partOptions.pinnedTabSizing !== 'normal' && typeof activeTabIndex === 'number' && this.tabsModel.isSticky(activeTabIndex);
1259
- let availableTabsContainerWidth = visibleTabsWidth - stickyTabsWidth;
1260
- if (this.tabsModel.stickyCount > 0 && availableTabsContainerWidth < MultiEditorTabsControl_1.TAB_WIDTH.fit) {
1261
- tabsContainer.classList.add('disable-sticky-tabs');
1262
- availableTabsContainerWidth = visibleTabsWidth;
1263
- stickyTabsWidth = 0;
1264
- activeTabPositionStatic = false;
1265
- }
1266
- else {
1267
- tabsContainer.classList.remove('disable-sticky-tabs');
1268
- }
1269
- let activeTabPosX;
1270
- let activeTabWidth;
1271
- if (!this.blockRevealActiveTab && activeTab) {
1272
- activeTabPosX = activeTab.offsetLeft;
1273
- activeTabWidth = activeTab.offsetWidth;
1274
- }
1275
- const { width: oldVisibleTabsWidth, scrollWidth: oldAllTabsWidth } = tabsScrollbar.getScrollDimensions();
1276
- tabsScrollbar.setScrollDimensions({
1277
- width: visibleTabsWidth,
1278
- scrollWidth: allTabsWidth
1279
- });
1280
- const dimensionsChanged = oldVisibleTabsWidth !== visibleTabsWidth || oldAllTabsWidth !== allTabsWidth;
1281
- if (this.blockRevealActiveTab ||
1282
- typeof activeTabPosX !== 'number' ||
1283
- typeof activeTabWidth !== 'number' ||
1284
- activeTabPositionStatic ||
1285
- (!dimensionsChanged && !options?.forceRevealActiveTab)
1286
- ) {
1287
- this.blockRevealActiveTab = false;
1288
- return;
1289
- }
1290
- const tabsContainerScrollPosX = tabsScrollbar.getScrollPosition().scrollLeft;
1291
- const activeTabFits = activeTabWidth <= availableTabsContainerWidth;
1292
- const adjustedActiveTabPosX = activeTabPosX - stickyTabsWidth;
1293
- if (activeTabFits && tabsContainerScrollPosX + availableTabsContainerWidth < adjustedActiveTabPosX + activeTabWidth) {
1294
- tabsScrollbar.setScrollPosition({
1295
- scrollLeft: tabsContainerScrollPosX + (((adjustedActiveTabPosX + activeTabWidth) - (tabsContainerScrollPosX + availableTabsContainerWidth)) )
1296
- });
1297
- }
1298
- else if (tabsContainerScrollPosX > adjustedActiveTabPosX || !activeTabFits) {
1299
- tabsScrollbar.setScrollPosition({
1300
- scrollLeft: adjustedActiveTabPosX
1301
- });
1302
- }
1303
- }
1304
- updateTabsControlVisibility() {
1305
- const tabsAndActionsContainer = assertIsDefined(this.tabsAndActionsContainer);
1306
- tabsAndActionsContainer.classList.toggle('empty', !this.visible);
1307
- if (!this.visible && this.dimensions) {
1308
- this.dimensions.used = undefined;
1309
- }
1310
- }
1311
- get visible() {
1312
- return this.tabsModel.count > 0;
1313
- }
1314
- getTabAndIndex(editor) {
1315
- const tabIndex = this.tabsModel.indexOf(editor);
1316
- const tab = this.getTabAtIndex(tabIndex);
1317
- if (tab) {
1318
- return [tab, tabIndex];
1319
- }
1320
- return undefined;
1321
- }
1322
- getTabAtIndex(tabIndex) {
1323
- if (tabIndex >= 0) {
1324
- const tabsContainer = assertIsDefined(this.tabsContainer);
1325
- return tabsContainer.children[tabIndex];
1326
- }
1327
- return undefined;
1328
- }
1329
- getLastTab() {
1330
- return this.getTabAtIndex(this.tabsModel.count - 1);
1331
- }
1332
- blockRevealActiveTabOnce() {
1333
- this.blockRevealActiveTab = true;
1334
- }
1335
- originatesFromTabActionBar(e) {
1336
- let element;
1337
- if (isMouseEvent(e)) {
1338
- element = (e.target || e.srcElement);
1339
- }
1340
- else {
1341
- element = e.initialTarget;
1342
- }
1343
- return !!findParentWithClass(element, 'action-item', 'tab');
1344
- }
1345
- async onDrop(e, targetTabIndex, tabsContainer) {
1346
- EventHelper.stop(e, true);
1347
- this.updateDropFeedback(tabsContainer, false);
1348
- tabsContainer.classList.remove('scroll');
1349
- const targetEditorIndex = this.tabsModel instanceof UnstickyEditorGroupModel ? targetTabIndex + this.groupView.stickyCount : targetTabIndex;
1350
- const options = {
1351
- sticky: this.tabsModel instanceof StickyEditorGroupModel && this.tabsModel.stickyCount === targetEditorIndex,
1352
- index: targetEditorIndex
1353
- };
1354
- if (this.groupTransfer.hasData(DraggedEditorGroupIdentifier.prototype)) {
1355
- const data = this.groupTransfer.getData(DraggedEditorGroupIdentifier.prototype);
1356
- if (Array.isArray(data)) {
1357
- const sourceGroup = this.editorPartsView.getGroup(data[0].identifier);
1358
- if (sourceGroup) {
1359
- const mergeGroupOptions = { index: targetEditorIndex };
1360
- if (!this.isMoveOperation(e, sourceGroup.id)) {
1361
- mergeGroupOptions.mode = 0 ;
1362
- }
1363
- this.groupsView.mergeGroup(sourceGroup, this.groupView, mergeGroupOptions);
1364
- }
1365
- this.groupView.focus();
1366
- this.groupTransfer.clearData(DraggedEditorGroupIdentifier.prototype);
1367
- }
1368
- }
1369
- else if (this.editorTransfer.hasData(DraggedEditorIdentifier.prototype)) {
1370
- const data = this.editorTransfer.getData(DraggedEditorIdentifier.prototype);
1371
- if (Array.isArray(data)) {
1372
- const draggedEditor = data[0].identifier;
1373
- const sourceGroup = this.editorPartsView.getGroup(draggedEditor.groupId);
1374
- if (sourceGroup) {
1375
- if (this.isMoveOperation(e, draggedEditor.groupId, draggedEditor.editor)) {
1376
- sourceGroup.moveEditor(draggedEditor.editor, this.groupView, options);
1377
- }
1378
- else {
1379
- sourceGroup.copyEditor(draggedEditor.editor, this.groupView, options);
1380
- }
1381
- }
1382
- this.groupView.focus();
1383
- this.editorTransfer.clearData(DraggedEditorIdentifier.prototype);
1384
- }
1385
- }
1386
- else if (this.treeItemsTransfer.hasData(DraggedTreeItemsIdentifier.prototype)) {
1387
- const data = this.treeItemsTransfer.getData(DraggedTreeItemsIdentifier.prototype);
1388
- if (Array.isArray(data)) {
1389
- const editors = [];
1390
- for (const id of data) {
1391
- const dataTransferItem = await this.treeViewsDragAndDropService.removeDragOperationTransfer(id.identifier);
1392
- if (dataTransferItem) {
1393
- const treeDropData = await extractTreeDropData(dataTransferItem);
1394
- editors.push(...( treeDropData.map(
1395
- editor => ({ ...editor, options: { ...editor.options, pinned: true, index: targetEditorIndex } })
1396
- )));
1397
- }
1398
- }
1399
- this.editorService.openEditors(editors, this.groupView, { validateTrust: true });
1400
- }
1401
- this.treeItemsTransfer.clearData(DraggedTreeItemsIdentifier.prototype);
1402
- }
1403
- else {
1404
- const dropHandler = this.instantiationService.createInstance(ResourcesDropHandler, { allowWorkspaceOpen: false });
1405
- dropHandler.handleDrop(e, getWindow(this.parent), () => this.groupView, () => this.groupView.focus(), options);
1406
- }
1407
- }
1408
- dispose() {
1409
- super.dispose();
1410
- this.tabDisposables = dispose(this.tabDisposables);
1411
- }
1412
- };
1413
- MultiEditorTabsControl = MultiEditorTabsControl_1 = ( __decorate([
1414
- ( __param(5, IContextMenuService)),
1415
- ( __param(6, IInstantiationService)),
1416
- ( __param(7, IContextKeyService)),
1417
- ( __param(8, IKeybindingService)),
1418
- ( __param(9, INotificationService)),
1419
- ( __param(10, IQuickInputService)),
1420
- ( __param(11, IThemeService)),
1421
- ( __param(12, IEditorService)),
1422
- ( __param(13, IPathService)),
1423
- ( __param(14, ITreeViewsDnDService)),
1424
- ( __param(15, IEditorResolverService)),
1425
- ( __param(16, IHostService))
1426
- ], MultiEditorTabsControl));
1427
- registerThemingParticipant((theme, collector) => {
1428
- const borderColor = theme.getColor(TAB_BORDER);
1429
- if (borderColor) {
1430
- collector.addRule(`
1431
- .monaco-workbench .part.editor > .content .editor-group-container > .title > .tabs-and-actions-container.wrapping .tabs-container > .tab {
1432
- border-bottom: 1px solid ${borderColor};
1433
- }
1434
- `);
1435
- }
1436
- const activeContrastBorderColor = theme.getColor(activeContrastBorder);
1437
- if (activeContrastBorderColor) {
1438
- collector.addRule(`
1439
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active,
1440
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active:hover {
1441
- outline: 1px solid;
1442
- outline-offset: -5px;
1443
- }
1444
-
1445
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab.active:focus {
1446
- outline-style: dashed;
1447
- }
1448
-
1449
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active {
1450
- outline: 1px dotted;
1451
- outline-offset: -5px;
1452
- }
1453
-
1454
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
1455
- outline: 1px dashed;
1456
- outline-offset: -5px;
1457
- }
1458
-
1459
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active > .tab-actions .action-label,
1460
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.active:hover > .tab-actions .action-label,
1461
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.dirty > .tab-actions .action-label,
1462
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.sticky > .tab-actions .action-label,
1463
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-actions .action-label {
1464
- opacity: 1 !important;
1465
- }
1466
- `);
1467
- }
1468
- const contrastBorderColor = theme.getColor(contrastBorder);
1469
- if (contrastBorderColor) {
1470
- collector.addRule(`
1471
- .monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions {
1472
- outline: 1px solid ${contrastBorderColor}
1473
- }
1474
- `);
1475
- }
1476
- const tabHoverBackground = theme.getColor(TAB_HOVER_BACKGROUND);
1477
- if (tabHoverBackground) {
1478
- collector.addRule(`
1479
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
1480
- background-color: ${tabHoverBackground} !important;
1481
- }
1482
- `);
1483
- }
1484
- const tabUnfocusedHoverBackground = theme.getColor(TAB_UNFOCUSED_HOVER_BACKGROUND);
1485
- if (tabUnfocusedHoverBackground) {
1486
- collector.addRule(`
1487
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
1488
- background-color: ${tabUnfocusedHoverBackground} !important;
1489
- }
1490
- `);
1491
- }
1492
- const tabHoverForeground = theme.getColor(TAB_HOVER_FOREGROUND);
1493
- if (tabHoverForeground) {
1494
- collector.addRule(`
1495
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover {
1496
- color: ${tabHoverForeground} !important;
1497
- }
1498
- `);
1499
- }
1500
- const tabUnfocusedHoverForeground = theme.getColor(TAB_UNFOCUSED_HOVER_FOREGROUND);
1501
- if (tabUnfocusedHoverForeground) {
1502
- collector.addRule(`
1503
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover {
1504
- color: ${tabUnfocusedHoverForeground} !important;
1505
- }
1506
- `);
1507
- }
1508
- const tabHoverBorder = theme.getColor(TAB_HOVER_BORDER);
1509
- if (tabHoverBorder) {
1510
- collector.addRule(`
1511
- .monaco-workbench .part.editor > .content .editor-group-container.active > .title .tabs-container > .tab:hover > .tab-border-bottom-container {
1512
- display: block;
1513
- position: absolute;
1514
- left: 0;
1515
- pointer-events: none;
1516
- width: 100%;
1517
- z-index: 10;
1518
- bottom: 0;
1519
- height: 1px;
1520
- background-color: ${tabHoverBorder};
1521
- }
1522
- `);
1523
- }
1524
- const tabUnfocusedHoverBorder = theme.getColor(TAB_UNFOCUSED_HOVER_BORDER);
1525
- if (tabUnfocusedHoverBorder) {
1526
- collector.addRule(`
1527
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab:hover > .tab-border-bottom-container {
1528
- display: block;
1529
- position: absolute;
1530
- left: 0;
1531
- pointer-events: none;
1532
- width: 100%;
1533
- z-index: 10;
1534
- bottom: 0;
1535
- height: 1px;
1536
- background-color: ${tabUnfocusedHoverBorder};
1537
- }
1538
- `);
1539
- }
1540
- if (!isHighContrast(theme.type) && !isSafari && !activeContrastBorderColor) {
1541
- const workbenchBackground = WORKBENCH_BACKGROUND(theme);
1542
- const editorBackgroundColor = theme.getColor(editorBackground);
1543
- const editorGroupHeaderTabsBackground = theme.getColor(EDITOR_GROUP_HEADER_TABS_BACKGROUND);
1544
- const editorDragAndDropBackground = theme.getColor(EDITOR_DRAG_AND_DROP_BACKGROUND);
1545
- let adjustedTabBackground;
1546
- if (editorGroupHeaderTabsBackground && editorBackgroundColor) {
1547
- adjustedTabBackground = editorGroupHeaderTabsBackground.flatten(editorBackgroundColor, editorBackgroundColor, workbenchBackground);
1548
- }
1549
- let adjustedTabDragBackground;
1550
- if (editorGroupHeaderTabsBackground && editorBackgroundColor && editorDragAndDropBackground && editorBackgroundColor) {
1551
- adjustedTabDragBackground = editorGroupHeaderTabsBackground.flatten(editorBackgroundColor, editorDragAndDropBackground, editorBackgroundColor, workbenchBackground);
1552
- }
1553
- const makeTabHoverBackgroundRule = (color, colorDrag, hasFocus = false) => `
1554
- .monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):not(.sticky-compact):hover > .tab-label > .monaco-icon-label-container::after,
1555
- .monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-fixed:not(.dragged):not(.sticky-compact):hover > .tab-label > .monaco-icon-label-container::after {
1556
- background: linear-gradient(to left, ${color}, transparent) !important;
1557
- }
1558
-
1559
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-shrink:not(.dragged):not(.sticky-compact):hover > .tab-label > .monaco-icon-label-container::after,
1560
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container${hasFocus ? '.active' : ''} > .title .tabs-container > .tab.sizing-fixed:not(.dragged):not(.sticky-compact):hover > .tab-label > .monaco-icon-label-container::after {
1561
- background: linear-gradient(to left, ${colorDrag}, transparent) !important;
1562
- }
1563
- `;
1564
- if (tabHoverBackground && adjustedTabBackground && adjustedTabDragBackground) {
1565
- const adjustedColor = tabHoverBackground.flatten(adjustedTabBackground);
1566
- const adjustedColorDrag = tabHoverBackground.flatten(adjustedTabDragBackground);
1567
- collector.addRule(makeTabHoverBackgroundRule(adjustedColor, adjustedColorDrag, true));
1568
- }
1569
- if (tabUnfocusedHoverBackground && adjustedTabBackground && adjustedTabDragBackground) {
1570
- const adjustedColor = tabUnfocusedHoverBackground.flatten(adjustedTabBackground);
1571
- const adjustedColorDrag = tabUnfocusedHoverBackground.flatten(adjustedTabDragBackground);
1572
- collector.addRule(makeTabHoverBackgroundRule(adjustedColor, adjustedColorDrag));
1573
- }
1574
- if (editorDragAndDropBackground && adjustedTabDragBackground) {
1575
- const adjustedColorDrag = editorDragAndDropBackground.flatten(adjustedTabDragBackground);
1576
- collector.addRule(`
1577
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.active):not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after,
1578
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-shrink.dragged-over:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after,
1579
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container.active > .title .tabs-container > .tab.sizing-fixed.dragged-over:not(.active):not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after,
1580
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container:not(.active) > .title .tabs-container > .tab.sizing-fixed.dragged-over:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after {
1581
- background: linear-gradient(to left, ${adjustedColorDrag}, transparent) !important;
1582
- }
1583
- `);
1584
- }
1585
- const makeTabBackgroundRule = (color, colorDrag, focused, active) => `
1586
- .monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink${active ? '.active' : ''}:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after,
1587
- .monaco-workbench .part.editor > .content:not(.dragged-over) .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-fixed${active ? '.active' : ''}:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after {
1588
- background: linear-gradient(to left, ${color}, transparent);
1589
- }
1590
-
1591
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-shrink${active ? '.active' : ''}:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after,
1592
- .monaco-workbench .part.editor > .content.dragged-over .editor-group-container${focused ? '.active' : ':not(.active)'} > .title .tabs-container > .tab.sizing-fixed${active ? '.active' : ''}:not(.dragged):not(.sticky-compact) > .tab-label > .monaco-icon-label-container::after {
1593
- background: linear-gradient(to left, ${colorDrag}, transparent);
1594
- }
1595
- `;
1596
- const tabActiveBackground = theme.getColor(TAB_ACTIVE_BACKGROUND);
1597
- if (tabActiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
1598
- const adjustedColor = tabActiveBackground.flatten(adjustedTabBackground);
1599
- const adjustedColorDrag = tabActiveBackground.flatten(adjustedTabDragBackground);
1600
- collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, true, true));
1601
- }
1602
- const tabUnfocusedActiveBackground = theme.getColor(TAB_UNFOCUSED_ACTIVE_BACKGROUND);
1603
- if (tabUnfocusedActiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
1604
- const adjustedColor = tabUnfocusedActiveBackground.flatten(adjustedTabBackground);
1605
- const adjustedColorDrag = tabUnfocusedActiveBackground.flatten(adjustedTabDragBackground);
1606
- collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, false, true));
1607
- }
1608
- const tabInactiveBackground = theme.getColor(TAB_INACTIVE_BACKGROUND);
1609
- if (tabInactiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
1610
- const adjustedColor = tabInactiveBackground.flatten(adjustedTabBackground);
1611
- const adjustedColorDrag = tabInactiveBackground.flatten(adjustedTabDragBackground);
1612
- collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, true, false));
1613
- }
1614
- const tabUnfocusedInactiveBackground = theme.getColor(TAB_UNFOCUSED_INACTIVE_BACKGROUND);
1615
- if (tabUnfocusedInactiveBackground && adjustedTabBackground && adjustedTabDragBackground) {
1616
- const adjustedColor = tabUnfocusedInactiveBackground.flatten(adjustedTabBackground);
1617
- const adjustedColorDrag = tabUnfocusedInactiveBackground.flatten(adjustedTabDragBackground);
1618
- collector.addRule(makeTabBackgroundRule(adjustedColor, adjustedColorDrag, false, false));
1619
- }
1620
- }
1621
- });
1622
-
1623
- export { MultiEditorTabsControl };