mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-30 08:40:29 -04:00
Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)
* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 * fix config changes * fix strictnull checks
This commit is contained in:
@@ -14,7 +14,7 @@ import { GlobalActivityActionViewItem, ViewletActivityAction, ToggleViewletActio
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IBadge } from 'vs/workbench/services/activity/common/activity';
|
||||
import { IWorkbenchLayoutService, Parts, Position as SideBarPosition } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
@@ -48,7 +48,7 @@ interface ICachedViewlet {
|
||||
|
||||
export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly ACTION_HEIGHT = 48;
|
||||
private static readonly PINNED_VIEWLETS = 'workbench.activity.pinnedViewlets';
|
||||
@@ -198,6 +198,8 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
|
||||
this.createGlobalActivityActionBar(globalActivities);
|
||||
|
||||
this.element.style.display = this.layoutService.isVisible(Parts.ACTIVITYBAR_PART) ? null : 'none';
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
@@ -368,6 +370,12 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
||||
.map(v => v.id);
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
if (this.element) {
|
||||
this.element.style.display = visible ? null : 'none';
|
||||
}
|
||||
}
|
||||
|
||||
layout(width: number, height: number): void {
|
||||
if (!this.layoutService.isVisible(Parts.ACTIVITYBAR_PART)) {
|
||||
return;
|
||||
|
||||
@@ -32,7 +32,6 @@ import { attachProgressBarStyler } from 'vs/platform/theme/common/styler';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { Dimension, append, $, addClass, hide, show, addClasses } from 'vs/base/browser/dom';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
export interface ICompositeTitleLabel {
|
||||
|
||||
@@ -240,7 +239,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
|
||||
// Update title with composite title if it differs from descriptor
|
||||
const descriptor = this.registry.getComposite(composite.getId());
|
||||
if (descriptor && descriptor.name !== composite.getTitle()) {
|
||||
this.updateTitle(composite.getId(), withNullAsUndefined(composite.getTitle()));
|
||||
this.updateTitle(composite.getId(), composite.getTitle());
|
||||
}
|
||||
|
||||
// Handle Composite Actions
|
||||
|
||||
@@ -41,8 +41,8 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
|
||||
readonly onDidSizeConstraintsChange: Event<{ width: number; height: number; } | undefined> = Event.None;
|
||||
|
||||
protected _input: EditorInput | null;
|
||||
protected _options: EditorOptions | null;
|
||||
protected _input: EditorInput | undefined;
|
||||
protected _options: EditorOptions | undefined;
|
||||
|
||||
private _group?: IEditorGroup;
|
||||
|
||||
@@ -55,11 +55,11 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
super(id, telemetryService, themeService, storageService);
|
||||
}
|
||||
|
||||
get input(): EditorInput | null {
|
||||
get input(): EditorInput | undefined {
|
||||
return this._input;
|
||||
}
|
||||
|
||||
get options(): EditorOptions | null {
|
||||
get options(): EditorOptions | undefined {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* The provided cancellation token should be used to test if the operation
|
||||
* was cancelled.
|
||||
*/
|
||||
setInput(input: EditorInput, options: EditorOptions | null, token: CancellationToken): Promise<void> {
|
||||
setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
this._input = input;
|
||||
this._options = options;
|
||||
|
||||
@@ -90,8 +90,8 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* resources associated with the input should be freed.
|
||||
*/
|
||||
clearInput(): void {
|
||||
this._input = null;
|
||||
this._options = null;
|
||||
this._input = undefined;
|
||||
this._options = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,7 +101,7 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
* Sets the given options to the editor. Clients should apply the options
|
||||
* to the current input.
|
||||
*/
|
||||
setOptions(options: EditorOptions | null): void {
|
||||
setOptions(options: EditorOptions | undefined): void {
|
||||
this._options = options;
|
||||
}
|
||||
|
||||
@@ -160,8 +160,8 @@ export abstract class BaseEditor extends Panel implements IEditor {
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._input = null;
|
||||
this._options = null;
|
||||
this._input = undefined;
|
||||
this._options = undefined;
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
@@ -172,7 +172,7 @@ interface MapGroupToMemento<T> {
|
||||
}
|
||||
|
||||
export class EditorMemento<T> implements IEditorMemento<T> {
|
||||
private cache: LRUCache<string, MapGroupToMemento<T>>;
|
||||
private cache: LRUCache<string, MapGroupToMemento<T>> | undefined;
|
||||
private cleanedUp = false;
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -23,7 +23,7 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export interface IOpenCallbacks {
|
||||
openInternal: (input: EditorInput, options: EditorOptions) => Promise<void>;
|
||||
openInternal: (input: EditorInput, options: EditorOptions | undefined) => Promise<void>;
|
||||
openExternal: (uri: URI) => void;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
parent.appendChild(this.scrollbar.getDomNode());
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, token);
|
||||
const model = await input.resolve();
|
||||
|
||||
@@ -102,7 +102,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
|
||||
}, this.instantiationService);
|
||||
}
|
||||
|
||||
private async handleOpenInternalCallback(input: EditorInput, options: EditorOptions): Promise<void> {
|
||||
private async handleOpenInternalCallback(input: EditorInput, options: EditorOptions | undefined): Promise<void> {
|
||||
await this.callbacks.openInternal(input, options);
|
||||
|
||||
// Signal to listeners that the binary editor has been opened in-place
|
||||
|
||||
@@ -11,7 +11,7 @@ import { localize } from 'vs/nls';
|
||||
import { IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { createDecorator, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
|
||||
@@ -19,7 +19,7 @@ export const IBreadcrumbsService = createDecorator<IBreadcrumbsService>('IEditor
|
||||
|
||||
export interface IBreadcrumbsService {
|
||||
|
||||
_serviceBrand: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
register(group: GroupIdentifier, widget: BreadcrumbsWidget): IDisposable;
|
||||
|
||||
@@ -29,7 +29,7 @@ export interface IBreadcrumbsService {
|
||||
|
||||
export class BreadcrumbsService implements IBreadcrumbsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly _map = new Map<number, BreadcrumbsWidget>();
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
|
||||
const labels = this._instantiationService.createInstance(ResourceLabels, DEFAULT_LABELS_CONTAINER /* TODO@Jo visibility propagation */);
|
||||
this._disposables.add(labels);
|
||||
|
||||
return this._instantiationService.createInstance(WorkbenchAsyncDataTree, container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), {
|
||||
return this._instantiationService.createInstance(WorkbenchAsyncDataTree, 'BreadcrumbsFilePicker', container, new FileVirtualDelegate(), [this._instantiationService.createInstance(FileRenderer, labels)], this._instantiationService.createInstance(FileDataSource), {
|
||||
multipleSelectionSupport: false,
|
||||
sorter: new FileSorter(),
|
||||
filter: this._instantiationService.createInstance(FileFilter),
|
||||
@@ -440,6 +440,7 @@ export class BreadcrumbsOutlinePicker extends BreadcrumbsPicker {
|
||||
protected _createTree(container: HTMLElement) {
|
||||
return this._instantiationService.createInstance(
|
||||
WorkbenchDataTree,
|
||||
'BreadcrumbsOutlinePicker',
|
||||
container,
|
||||
new OutlineVirtualDelegate(),
|
||||
[new OutlineGroupRenderer(), this._instantiationService.createInstance(OutlineElementRenderer)],
|
||||
|
||||
@@ -52,6 +52,7 @@ import { toLocalResource } from 'vs/base/common/resources';
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { registerAndGetAmdImageURL } from 'vs/base/common/amd';
|
||||
|
||||
// Register String Editor
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
|
||||
@@ -234,7 +235,7 @@ registry.registerWorkbenchAction(new SyncActionDescriptor(ChangeEOLAction, Chang
|
||||
registry.registerWorkbenchAction(new SyncActionDescriptor(ChangeEncodingAction, ChangeEncodingAction.ID, ChangeEncodingAction.LABEL), 'Change File Encoding');
|
||||
|
||||
export class QuickOpenActionContributor extends ActionBarContributor {
|
||||
private openToSideActionInstance: OpenToSideFromQuickOpenAction;
|
||||
private openToSideActionInstance: OpenToSideFromQuickOpenAction | undefined;
|
||||
|
||||
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
|
||||
super();
|
||||
@@ -417,12 +418,12 @@ editorCommands.setup();
|
||||
// Touch Bar
|
||||
if (isMacintosh) {
|
||||
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
||||
command: { id: NavigateBackwardsAction.ID, title: NavigateBackwardsAction.LABEL, iconLocation: { dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/back-tb.png')) } },
|
||||
command: { id: NavigateBackwardsAction.ID, title: NavigateBackwardsAction.LABEL, iconLocation: { dark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/back-tb.png')) } },
|
||||
group: 'navigation'
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.TouchBarContext, {
|
||||
command: { id: NavigateForwardAction.ID, title: NavigateForwardAction.LABEL, iconLocation: { dark: URI.parse(require.toUrl('vs/workbench/browser/parts/editor/media/forward-tb.png')) } },
|
||||
command: { id: NavigateForwardAction.ID, title: NavigateForwardAction.LABEL, iconLocation: { dark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/forward-tb.png')) } },
|
||||
group: 'navigation'
|
||||
});
|
||||
}
|
||||
@@ -452,7 +453,7 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID, title: nls.localize('closeAll', "Close All") }, group: '5_close', order: 10, when: ContextKeyExpr.has('config.workbench.editor.showTabs') });
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, { command: { id: editorCommands.CLOSE_SAVED_EDITORS_COMMAND_ID, title: nls.localize('closeAllSaved', "Close Saved") }, group: '5_close', order: 20, when: ContextKeyExpr.has('config.workbench.editor.showTabs') });
|
||||
|
||||
interface IEditorToolItem { id: string; title: string; iconDark: string; iconLight: string; }
|
||||
interface IEditorToolItem { id: string; title: string; iconDark: URI; iconLight: URI; }
|
||||
|
||||
function appendEditorToolItem(primary: IEditorToolItem, when: ContextKeyExpr | undefined, order: number, alternative?: IEditorToolItem): void {
|
||||
const item: IMenuItem = {
|
||||
@@ -460,8 +461,8 @@ function appendEditorToolItem(primary: IEditorToolItem, when: ContextKeyExpr | u
|
||||
id: primary.id,
|
||||
title: primary.title,
|
||||
iconLocation: {
|
||||
dark: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${primary.iconDark}`)),
|
||||
light: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${primary.iconLight}`))
|
||||
dark: primary.iconDark,
|
||||
light: primary.iconLight
|
||||
}
|
||||
},
|
||||
group: 'navigation',
|
||||
@@ -474,8 +475,8 @@ function appendEditorToolItem(primary: IEditorToolItem, when: ContextKeyExpr | u
|
||||
id: alternative.id,
|
||||
title: alternative.title,
|
||||
iconLocation: {
|
||||
dark: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${alternative.iconDark}`)),
|
||||
light: URI.parse(require.toUrl(`vs/workbench/browser/parts/editor/media/${alternative.iconLight}`))
|
||||
dark: alternative.iconDark,
|
||||
light: alternative.iconLight
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -483,21 +484,26 @@ function appendEditorToolItem(primary: IEditorToolItem, when: ContextKeyExpr | u
|
||||
MenuRegistry.appendMenuItem(MenuId.EditorTitle, item);
|
||||
}
|
||||
|
||||
const SPLIT_EDITOR_HORIZONTAL_DARK_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/split-editor-horizontal-dark.svg'));
|
||||
const SPLIT_EDITOR_HORIZONTAL_LIGHT_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/split-editor-horizontal-light.svg'));
|
||||
const SPLIT_EDITOR_VERTICAL_DARK_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/split-editor-vertical-dark.svg'));
|
||||
const SPLIT_EDITOR_VERTICAL_LIGHT_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/split-editor-vertical-light.svg'));
|
||||
|
||||
// Editor Title Menu: Split Editor
|
||||
appendEditorToolItem(
|
||||
{
|
||||
id: SplitEditorAction.ID,
|
||||
title: nls.localize('splitEditorRight', "Split Editor Right"),
|
||||
iconDark: 'split-editor-horizontal-dark.svg',
|
||||
iconLight: 'split-editor-horizontal-light.svg'
|
||||
iconDark: SPLIT_EDITOR_HORIZONTAL_DARK_ICON,
|
||||
iconLight: SPLIT_EDITOR_HORIZONTAL_LIGHT_ICON
|
||||
},
|
||||
ContextKeyExpr.not('splitEditorsVertically'),
|
||||
100000, // towards the end
|
||||
{
|
||||
id: editorCommands.SPLIT_EDITOR_DOWN,
|
||||
title: nls.localize('splitEditorDown', "Split Editor Down"),
|
||||
iconDark: 'split-editor-vertical-dark.svg',
|
||||
iconLight: 'split-editor-vertical-light.svg'
|
||||
iconDark: SPLIT_EDITOR_VERTICAL_DARK_ICON,
|
||||
iconLight: SPLIT_EDITOR_VERTICAL_LIGHT_ICON
|
||||
}
|
||||
);
|
||||
|
||||
@@ -505,34 +511,37 @@ appendEditorToolItem(
|
||||
{
|
||||
id: SplitEditorAction.ID,
|
||||
title: nls.localize('splitEditorDown', "Split Editor Down"),
|
||||
iconDark: 'split-editor-vertical-dark.svg',
|
||||
iconLight: 'split-editor-vertical-light.svg'
|
||||
iconDark: SPLIT_EDITOR_VERTICAL_DARK_ICON,
|
||||
iconLight: SPLIT_EDITOR_VERTICAL_LIGHT_ICON
|
||||
},
|
||||
ContextKeyExpr.has('splitEditorsVertically'),
|
||||
100000, // towards the end
|
||||
{
|
||||
id: editorCommands.SPLIT_EDITOR_RIGHT,
|
||||
title: nls.localize('splitEditorRight', "Split Editor Right"),
|
||||
iconDark: 'split-editor-horizontal-dark.svg',
|
||||
iconLight: 'split-editor-horizontal-light.svg'
|
||||
iconDark: SPLIT_EDITOR_HORIZONTAL_DARK_ICON,
|
||||
iconLight: SPLIT_EDITOR_HORIZONTAL_LIGHT_ICON
|
||||
}
|
||||
);
|
||||
|
||||
const CLOSE_ALL_DARK_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-all-dark.svg'));
|
||||
const CLOSE_ALL_LIGHT_ICON = URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-all-light.svg'));
|
||||
|
||||
// Editor Title Menu: Close Group (tabs disabled)
|
||||
appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
iconDark: 'close-dark-alt.svg',
|
||||
iconLight: 'close-light-alt.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-dark-alt.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-light-alt.svg'))
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ContextKeyExpr.not('groupActiveEditorDirty')),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
title: nls.localize('closeAll', "Close All"),
|
||||
iconDark: 'close-all-dark.svg',
|
||||
iconLight: 'close-all-light.svg'
|
||||
iconDark: CLOSE_ALL_DARK_ICON,
|
||||
iconLight: CLOSE_ALL_LIGHT_ICON
|
||||
}
|
||||
);
|
||||
|
||||
@@ -540,16 +549,16 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITOR_COMMAND_ID,
|
||||
title: nls.localize('close', "Close"),
|
||||
iconDark: 'close-dirty-dark-alt.svg',
|
||||
iconLight: 'close-dirty-light-alt.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-dirty-dark-alt.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/close-dirty-light-alt.svg'))
|
||||
},
|
||||
ContextKeyExpr.and(ContextKeyExpr.not('config.workbench.editor.showTabs'), ContextKeyExpr.has('groupActiveEditorDirty')),
|
||||
1000000, // towards the far end
|
||||
{
|
||||
id: editorCommands.CLOSE_EDITORS_IN_GROUP_COMMAND_ID,
|
||||
title: nls.localize('closeAll', "Close All"),
|
||||
iconDark: 'close-all-dark.svg',
|
||||
iconLight: 'close-all-light.svg'
|
||||
iconDark: CLOSE_ALL_DARK_ICON,
|
||||
iconLight: CLOSE_ALL_LIGHT_ICON
|
||||
}
|
||||
);
|
||||
|
||||
@@ -558,8 +567,8 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.GOTO_PREVIOUS_CHANGE,
|
||||
title: nls.localize('navigate.prev.label', "Previous Change"),
|
||||
iconDark: 'previous-diff-dark.svg',
|
||||
iconLight: 'previous-diff-light.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/previous-diff-dark.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/previous-diff-light.svg'))
|
||||
},
|
||||
TextCompareEditorActiveContext,
|
||||
10
|
||||
@@ -570,8 +579,8 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.GOTO_NEXT_CHANGE,
|
||||
title: nls.localize('navigate.next.label', "Next Change"),
|
||||
iconDark: 'next-diff-dark.svg',
|
||||
iconLight: 'next-diff-light.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/next-diff-dark.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/next-diff-light.svg'))
|
||||
},
|
||||
TextCompareEditorActiveContext,
|
||||
11
|
||||
@@ -582,8 +591,8 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE,
|
||||
title: nls.localize('ignoreTrimWhitespace.label', "Ignore Trim Whitespace"),
|
||||
iconDark: 'paragraph-dark.svg',
|
||||
iconLight: 'paragraph-light.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/paragraph-dark.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/paragraph-light.svg'))
|
||||
},
|
||||
ContextKeyExpr.and(TextCompareEditorActiveContext, ContextKeyExpr.notEquals('config.diffEditor.ignoreTrimWhitespace', true)),
|
||||
20
|
||||
@@ -594,8 +603,8 @@ appendEditorToolItem(
|
||||
{
|
||||
id: editorCommands.TOGGLE_DIFF_IGNORE_TRIM_WHITESPACE,
|
||||
title: nls.localize('showTrimWhitespace.label', "Show Trim Whitespace"),
|
||||
iconDark: 'paragraph-disabled-dark.svg',
|
||||
iconLight: 'paragraph-disabled-light.svg'
|
||||
iconDark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/paragraph-disabled-dark.svg')),
|
||||
iconLight: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/editor/media/paragraph-disabled-light.svg'))
|
||||
},
|
||||
ContextKeyExpr.and(TextCompareEditorActiveContext, ContextKeyExpr.notEquals('config.diffEditor.ignoreTrimWhitespace', false)),
|
||||
20
|
||||
|
||||
@@ -263,7 +263,10 @@ function registerDiffEditorCommands(): void {
|
||||
const candidates = [editorService.activeControl, ...editorService.visibleControls].filter(e => e instanceof TextDiffEditor);
|
||||
|
||||
if (candidates.length > 0) {
|
||||
next ? (<TextDiffEditor>candidates[0]).getDiffNavigator().next() : (<TextDiffEditor>candidates[0]).getDiffNavigator().previous();
|
||||
const navigator = (<TextDiffEditor>candidates[0]).getDiffNavigator();
|
||||
if (navigator) {
|
||||
next ? navigator.next() : navigator.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import { IEditorProgressService, LongRunningOperation } from 'vs/platform/progre
|
||||
import { IEditorGroupView, DEFAULT_EDITOR_MIN_DIMENSIONS, DEFAULT_EDITOR_MAX_DIMENSIONS } from 'vs/workbench/browser/parts/editor/editor';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IVisibleEditor } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
|
||||
export interface IOpenEditorResult {
|
||||
readonly control: BaseEditor;
|
||||
@@ -35,11 +34,11 @@ export class EditorControl extends Disposable {
|
||||
private _onDidSizeConstraintsChange = this._register(new Emitter<{ width: number; height: number; } | undefined>());
|
||||
get onDidSizeConstraintsChange(): Event<{ width: number; height: number; } | undefined> { return this._onDidSizeConstraintsChange.event; }
|
||||
|
||||
private _activeControl: BaseEditor | null;
|
||||
private _activeControl: BaseEditor | null = null;
|
||||
private controls: BaseEditor[] = [];
|
||||
|
||||
private readonly activeControlDisposables = this._register(new DisposableStore());
|
||||
private dimension: Dimension;
|
||||
private dimension: Dimension | undefined;
|
||||
private editorOperation: LongRunningOperation;
|
||||
|
||||
constructor(
|
||||
@@ -68,7 +67,7 @@ export class EditorControl extends Disposable {
|
||||
const control = this.doShowEditorControl(descriptor);
|
||||
|
||||
// Set input
|
||||
const editorChanged = await this.doSetInput(control, editor, withUndefinedAsNull(options));
|
||||
const editorChanged = await this.doSetInput(control, editor, options);
|
||||
return { control, editorChanged };
|
||||
}
|
||||
|
||||
@@ -151,7 +150,7 @@ export class EditorControl extends Disposable {
|
||||
this._onDidSizeConstraintsChange.fire(undefined);
|
||||
}
|
||||
|
||||
private async doSetInput(control: BaseEditor, editor: EditorInput, options: EditorOptions | null): Promise<boolean> {
|
||||
private async doSetInput(control: BaseEditor, editor: EditorInput, options: EditorOptions | undefined): Promise<boolean> {
|
||||
|
||||
// If the input did not change, return early and only apply the options
|
||||
// unless the options instruct us to force open it even if it is the same
|
||||
|
||||
@@ -25,11 +25,11 @@ class DropOverlay extends Themable {
|
||||
|
||||
private static OVERLAY_ID = 'monaco-workbench-editor-drop-overlay';
|
||||
|
||||
private container: HTMLElement;
|
||||
private overlay: HTMLElement;
|
||||
private container!: HTMLElement;
|
||||
private overlay!: HTMLElement;
|
||||
|
||||
private currentDropOperation?: IDropOperation;
|
||||
private _disposed: boolean;
|
||||
private currentDropOperation: IDropOperation | undefined;
|
||||
private _disposed: boolean | undefined;
|
||||
|
||||
private cleanupOverlayScheduler: RunOnceScheduler;
|
||||
|
||||
@@ -50,7 +50,7 @@ class DropOverlay extends Themable {
|
||||
}
|
||||
|
||||
get disposed(): boolean {
|
||||
return this._disposed;
|
||||
return !!this._disposed;
|
||||
}
|
||||
|
||||
private create(): void {
|
||||
|
||||
@@ -817,7 +817,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
this._onWillOpenEditor.fire(event);
|
||||
const prevented = event.isPrevented();
|
||||
if (prevented) {
|
||||
return prevented();
|
||||
return withUndefinedAsNull(await prevented());
|
||||
}
|
||||
|
||||
// Proceed with opening
|
||||
@@ -846,9 +846,13 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
if (options && options.activation === EditorActivation.ACTIVATE) {
|
||||
// Respect option to force activate an editor group.
|
||||
activateGroup = true;
|
||||
} else if (options && options.activation === EditorActivation.RESTORE) {
|
||||
// Respect option to force restore an editor group.
|
||||
restoreGroup = true;
|
||||
} else if (options && options.activation === EditorActivation.PRESERVE) {
|
||||
// Respect option to preserve active editor group.
|
||||
activateGroup = false;
|
||||
restoreGroup = false;
|
||||
} else if (openEditorOptions.active) {
|
||||
// Finally, we only activate/restore an editor which is
|
||||
// opening as active editor.
|
||||
@@ -1524,7 +1528,7 @@ export class EditorGroupView extends Themable implements IEditorGroupView {
|
||||
}
|
||||
|
||||
class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
private override: () => Promise<IEditor>;
|
||||
private override: () => Promise<IEditor | undefined>;
|
||||
|
||||
constructor(
|
||||
private _group: GroupIdentifier,
|
||||
@@ -1545,11 +1549,11 @@ class EditorOpeningEvent implements IEditorOpeningEvent {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
prevent(callback: () => Promise<IEditor>): void {
|
||||
prevent(callback: () => Promise<IEditor | undefined>): void {
|
||||
this.override = callback;
|
||||
}
|
||||
|
||||
isPrevented(): () => Promise<IEditor> {
|
||||
isPrevented(): () => Promise<IEditor | undefined> {
|
||||
return this.override;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Dimension, isAncestor, toggleClass, addClass, $ } from 'vs/base/browser
|
||||
import { Event, Emitter, Relay } from 'vs/base/common/event';
|
||||
import { contrastBorder, editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { GroupDirection, IAddGroupOptions, GroupsArrangement, GroupOrientation, IMergeGroupOptions, MergeGroupMode, ICopyEditorOptions, GroupsOrder, GroupChangeKind, GroupLocation, IFindGroupScope, EditorGroupLayout, GroupLayoutArgument, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IView, orthogonal, LayoutPriority, IViewSize, Direction, SerializableGrid, Sizing, ISerializedGrid, Orientation, GridBranchNode, isGridBranchNode, GridNode, createSerializedGrid, Grid } from 'vs/base/browser/ui/grid/grid';
|
||||
import { GroupIdentifier, IWorkbenchEditorConfiguration, IEditorPartOptions } from 'vs/workbench/common/editor';
|
||||
import { values } from 'vs/base/common/map';
|
||||
@@ -81,7 +81,7 @@ class GridWidgetView<T extends IView> implements IView {
|
||||
|
||||
export class EditorPart extends Part implements IEditorGroupsService, IEditorGroupsAccessor {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly EDITOR_PART_UI_STATE_STORAGE_KEY = 'editorpart.state';
|
||||
private static readonly EDITOR_PART_CENTERED_VIEW_STORAGE_KEY = 'editorpart.centeredview';
|
||||
@@ -140,7 +140,7 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
|
||||
) {
|
||||
super(Parts.EDITOR_PART, { hasTitle: false }, themeService, storageService, layoutService);
|
||||
|
||||
@@ -780,14 +780,15 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro
|
||||
|
||||
//#region Part
|
||||
|
||||
get minimumWidth(): number { return this.centeredLayoutWidget.minimumWidth; }
|
||||
// TODO @sbatten @joao find something better to prevent editor taking over #79897
|
||||
get minimumWidth(): number { return Math.min(this.centeredLayoutWidget.minimumWidth, this.layoutService.getMaximumEditorDimensions().width); }
|
||||
get maximumWidth(): number { return this.centeredLayoutWidget.maximumWidth; }
|
||||
get minimumHeight(): number { return this.centeredLayoutWidget.minimumHeight; }
|
||||
get minimumHeight(): number { return Math.min(this.centeredLayoutWidget.minimumHeight, this.layoutService.getMaximumEditorDimensions().height); }
|
||||
get maximumHeight(): number { return this.centeredLayoutWidget.maximumHeight; }
|
||||
|
||||
readonly snap = true;
|
||||
|
||||
get onDidChange(): Event<IViewSize | undefined> { return this.centeredLayoutWidget.onDidChange; }
|
||||
get onDidChange(): Event<IViewSize | undefined> { return Event.any(this.centeredLayoutWidget.onDidChange, this.onDidSetGridWidget.event); }
|
||||
readonly priority: LayoutPriority = LayoutPriority.High;
|
||||
|
||||
private get gridSeparatorBorder(): Color {
|
||||
|
||||
@@ -35,7 +35,7 @@ import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/c
|
||||
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { ITextFileService, SUPPORTED_ENCODINGS } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
|
||||
import { IConfigurationChangedEvent, IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { ConfigurationChangedEvent, IEditorOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
@@ -328,7 +328,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
if (!this.screenReaderNotification) {
|
||||
this.screenReaderNotification = this.notificationService.prompt(
|
||||
Severity.Info,
|
||||
nls.localize('screenReaderDetectedExplanation.question', "Are you using a screen reader to operate Azure Data Studio? (Certain features like folding, minimap or word wrap are disabled when using a screen reader)"),
|
||||
nls.localize('screenReaderDetectedExplanation.question', "Are you using a screen reader to operate Azure Data Studio? (Certain features like word wrap are disabled when using a screen reader)"), // {{SQL CARBON EDIT}} change vscode to ads
|
||||
[{
|
||||
label: nls.localize('screenReaderDetectedExplanation.answerYes', "Yes"),
|
||||
run: () => {
|
||||
@@ -586,8 +586,8 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
if (activeCodeEditor) {
|
||||
|
||||
// Hook Listener for Configuration changes
|
||||
this.activeEditorListeners.add(activeCodeEditor.onDidChangeConfiguration((event: IConfigurationChangedEvent) => {
|
||||
if (event.accessibilitySupport) {
|
||||
this.activeEditorListeners.add(activeCodeEditor.onDidChangeConfiguration((event: ConfigurationChangedEvent) => {
|
||||
if (event.hasChanged(EditorOption.accessibilitySupport)) {
|
||||
this.onScreenReaderModeChange(activeCodeEditor);
|
||||
}
|
||||
}));
|
||||
@@ -711,7 +711,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
}
|
||||
}
|
||||
|
||||
screenReaderMode = (editorWidget.getConfiguration().accessibilitySupport === AccessibilitySupport.Enabled);
|
||||
screenReaderMode = (editorWidget.getOption(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled);
|
||||
}
|
||||
|
||||
if (screenReaderMode === false && this.screenReaderNotification) {
|
||||
@@ -761,7 +761,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
|
||||
private onEOLChange(editorWidget: ICodeEditor | undefined): void {
|
||||
const info: StateDelta = { EOL: undefined };
|
||||
|
||||
if (editorWidget && !editorWidget.getConfiguration().readOnly) {
|
||||
if (editorWidget && !editorWidget.getOption(EditorOption.readOnly)) {
|
||||
const codeEditorModel = editorWidget.getModel();
|
||||
if (codeEditorModel) {
|
||||
info.EOL = codeEditorModel.getEOL();
|
||||
@@ -822,8 +822,7 @@ function isWritableCodeEditor(codeEditor: ICodeEditor | undefined): boolean {
|
||||
if (!codeEditor) {
|
||||
return false;
|
||||
}
|
||||
const config = codeEditor.getConfiguration();
|
||||
return (!config.readOnly);
|
||||
return !codeEditor.getOption(EditorOption.readOnly);
|
||||
}
|
||||
|
||||
function isWritableBaseEditor(e: IBaseEditor): boolean {
|
||||
@@ -1169,7 +1168,7 @@ export class ChangeEncodingAction extends Action {
|
||||
|
||||
let guessedEncoding: string | undefined = undefined;
|
||||
if (this.fileService.canHandleResource(resource)) {
|
||||
const content = await this.textFileService.read(resource, { autoGuessEncoding: true, acceptTextOnly: true });
|
||||
const content = await this.textFileService.read(resource, { autoGuessEncoding: true });
|
||||
guessedEncoding = content.encoding;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><circle fill="#C5C5C5" cx="8" cy="8" r="4"/></svg>
|
||||
|
Before Width: | Height: | Size: 167 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" enable-background="new 0 0 16 16" height="16" width="16"><circle fill="#C5C5C5" cx="8" cy="8" r="4"/></svg>
|
||||
|
Before Width: | Height: | Size: 167 B |
@@ -81,6 +81,7 @@
|
||||
display: flex;
|
||||
flex: initial;
|
||||
opacity: 0.5;
|
||||
padding-right: 8px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,52 +12,6 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer.image {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer.image img {
|
||||
padding: 0;
|
||||
background-position: 0 0, 8px 8px;
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
.vs .monaco-resource-viewer.image img {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230)),
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230));
|
||||
}
|
||||
|
||||
.vs-dark .monaco-resource-viewer.image img {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20)),
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20));
|
||||
}
|
||||
|
||||
.monaco-resource-viewer img.pixelated {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer img.scale-to-fit {
|
||||
max-width: calc(100% - 20px);
|
||||
max-height: calc(100% - 20px);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer img {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer.zoom-in {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer.zoom-out {
|
||||
cursor: zoom-out;
|
||||
}
|
||||
|
||||
.monaco-resource-viewer .embedded-link,
|
||||
.monaco-resource-viewer .embedded-link:hover {
|
||||
cursor: pointer;
|
||||
|
||||
@@ -268,7 +268,7 @@
|
||||
.monaco-workbench .part.editor > .content .editor-group-container > .title .editor-actions {
|
||||
cursor: default;
|
||||
flex: initial;
|
||||
padding-left: 4px;
|
||||
padding: 0 8px 0 4px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,25 +3,16 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/resourceviewer';
|
||||
import * as nls from 'vs/nls';
|
||||
import * as mimes from 'vs/base/common/mime';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { LRUCache } from 'vs/base/common/map';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { clamp } from 'vs/base/common/numbers';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IDisposable, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import 'vs/css!./media/resourceviewer';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITheme, registerThemingParticipant, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { ICssStyleCollector, ITheme, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { IMAGE_PREVIEW_BORDER } from 'vs/workbench/common/theme';
|
||||
|
||||
export interface IResourceDescriptor {
|
||||
@@ -94,11 +85,6 @@ export class ResourceViewer {
|
||||
// Ensure CSS class
|
||||
container.className = 'monaco-resource-viewer';
|
||||
|
||||
// Images
|
||||
if (ResourceViewer.isImageResource(descriptor)) {
|
||||
return ImageView.create(container, descriptor, fileService, scrollbar, delegate, instantiationService);
|
||||
}
|
||||
|
||||
// Large Files
|
||||
if (descriptor.size > ResourceViewer.MAX_OPEN_INTERNAL_SIZE) {
|
||||
return FileTooLargeFileView.create(container, descriptor, scrollbar, delegate);
|
||||
@@ -110,82 +96,8 @@ export class ResourceViewer {
|
||||
}
|
||||
}
|
||||
|
||||
private static isImageResource(descriptor: IResourceDescriptor) {
|
||||
const mime = getMime(descriptor);
|
||||
|
||||
// Chrome does not support tiffs
|
||||
return mime.indexOf('image/') >= 0 && mime !== 'image/tiff';
|
||||
}
|
||||
}
|
||||
|
||||
class ImageView {
|
||||
private static readonly MAX_IMAGE_SIZE = BinarySize.MB * 10; // showing images inline is memory intense, so we have a limit
|
||||
private static readonly BASE64_MARKER = 'base64,';
|
||||
|
||||
static create(
|
||||
container: HTMLElement,
|
||||
descriptor: IResourceDescriptor,
|
||||
fileService: IFileService,
|
||||
scrollbar: DomScrollableElement,
|
||||
delegate: ResourceViewerDelegate,
|
||||
instantiationService: IInstantiationService,
|
||||
): ResourceViewerContext {
|
||||
if (ImageView.shouldShowImageInline(descriptor)) {
|
||||
return InlineImageView.create(container, descriptor, fileService, scrollbar, delegate, instantiationService);
|
||||
}
|
||||
|
||||
return LargeImageView.create(container, descriptor, delegate);
|
||||
}
|
||||
|
||||
private static shouldShowImageInline(descriptor: IResourceDescriptor): boolean {
|
||||
let skipInlineImage: boolean;
|
||||
|
||||
// Data URI
|
||||
if (descriptor.resource.scheme === Schemas.data) {
|
||||
const base64MarkerIndex = descriptor.resource.path.indexOf(ImageView.BASE64_MARKER);
|
||||
const hasData = base64MarkerIndex >= 0 && descriptor.resource.path.substring(base64MarkerIndex + ImageView.BASE64_MARKER.length).length > 0;
|
||||
|
||||
skipInlineImage = !hasData || descriptor.size > ImageView.MAX_IMAGE_SIZE || descriptor.resource.path.length > ImageView.MAX_IMAGE_SIZE;
|
||||
}
|
||||
|
||||
// File URI
|
||||
else {
|
||||
skipInlineImage = typeof descriptor.size !== 'number' || descriptor.size > ImageView.MAX_IMAGE_SIZE;
|
||||
}
|
||||
|
||||
return !skipInlineImage;
|
||||
}
|
||||
}
|
||||
|
||||
class LargeImageView {
|
||||
static create(
|
||||
container: HTMLElement,
|
||||
descriptor: IResourceDescriptor,
|
||||
delegate: ResourceViewerDelegate
|
||||
) {
|
||||
const size = BinarySize.formatSize(descriptor.size);
|
||||
delegate.metadataClb(size);
|
||||
|
||||
DOM.clearNode(container);
|
||||
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const label = document.createElement('p');
|
||||
label.textContent = nls.localize('largeImageError', "The image is not displayed in the editor because it is too large ({0}).", size);
|
||||
container.appendChild(label);
|
||||
|
||||
const openExternal = delegate.openExternalClb;
|
||||
if (descriptor.resource.scheme === Schemas.file && openExternal) {
|
||||
const link = DOM.append(label, DOM.$('a.embedded-link'));
|
||||
link.setAttribute('role', 'button');
|
||||
link.textContent = nls.localize('resourceOpenExternalButton', "Open image using external program?");
|
||||
|
||||
disposables.add(DOM.addDisposableListener(link, DOM.EventType.CLICK, () => openExternal(descriptor.resource)));
|
||||
}
|
||||
|
||||
return disposables;
|
||||
}
|
||||
}
|
||||
|
||||
class FileTooLargeFileView {
|
||||
static create(
|
||||
@@ -239,349 +151,3 @@ class FileSeemsBinaryFileView {
|
||||
return disposables;
|
||||
}
|
||||
}
|
||||
|
||||
type Scale = number | 'fit';
|
||||
|
||||
export class ZoomStatusbarItem extends Disposable {
|
||||
|
||||
private statusbarItem?: IStatusbarEntryAccessor;
|
||||
|
||||
constructor(
|
||||
private readonly onSelectScale: (scale: Scale) => void,
|
||||
@IEditorService editorService: IEditorService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IStatusbarService private readonly statusbarService: IStatusbarService,
|
||||
) {
|
||||
super();
|
||||
this._register(editorService.onDidActiveEditorChange(() => {
|
||||
if (this.statusbarItem) {
|
||||
this.statusbarItem.dispose();
|
||||
this.statusbarItem = undefined;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
updateStatusbar(scale: Scale): void {
|
||||
const entry: IStatusbarEntry = {
|
||||
text: this.zoomLabel(scale)
|
||||
};
|
||||
|
||||
if (!this.statusbarItem) {
|
||||
this.statusbarItem = this.statusbarService.addEntry(entry, 'status.imageZoom', nls.localize('status.imageZoom', "Image Zoom"), StatusbarAlignment.RIGHT, 101 /* to the left of editor status (100) */);
|
||||
|
||||
this._register(this.statusbarItem);
|
||||
|
||||
const element = document.getElementById('status.imageZoom')!;
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CLICK, (e: MouseEvent) => {
|
||||
this.contextMenuService.showContextMenu({
|
||||
getAnchor: () => element,
|
||||
getActions: () => this.zoomActions
|
||||
});
|
||||
}));
|
||||
} else {
|
||||
this.statusbarItem.update(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@memoize
|
||||
private get zoomActions(): Action[] {
|
||||
const scales: Scale[] = [10, 5, 2, 1, 0.5, 0.2, 'fit'];
|
||||
return scales.map(scale =>
|
||||
new Action(`zoom.${scale}`, this.zoomLabel(scale), undefined, undefined, () => {
|
||||
this.updateStatusbar(scale);
|
||||
if (this.onSelectScale) {
|
||||
this.onSelectScale(scale);
|
||||
}
|
||||
|
||||
return Promise.resolve(undefined);
|
||||
}));
|
||||
}
|
||||
|
||||
private zoomLabel(scale: Scale): string {
|
||||
return scale === 'fit'
|
||||
? nls.localize('zoom.action.fit.label', 'Whole Image')
|
||||
: `${Math.round(scale * 100)}%`;
|
||||
}
|
||||
}
|
||||
|
||||
interface ImageState {
|
||||
scale: Scale;
|
||||
offsetX: number;
|
||||
offsetY: number;
|
||||
}
|
||||
|
||||
class InlineImageView {
|
||||
private static readonly SCALE_PINCH_FACTOR = 0.075;
|
||||
private static readonly MAX_SCALE = 20;
|
||||
private static readonly MIN_SCALE = 0.1;
|
||||
|
||||
private static readonly zoomLevels: Scale[] = [
|
||||
0.1,
|
||||
0.2,
|
||||
0.3,
|
||||
0.4,
|
||||
0.5,
|
||||
0.6,
|
||||
0.7,
|
||||
0.8,
|
||||
0.9,
|
||||
1,
|
||||
1.5,
|
||||
2,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
10,
|
||||
15,
|
||||
20
|
||||
];
|
||||
|
||||
/**
|
||||
* Enable image-rendering: pixelated for images scaled by more than this.
|
||||
*/
|
||||
private static readonly PIXELATION_THRESHOLD = 3;
|
||||
|
||||
/**
|
||||
* Store the scale and position of an image so it can be restored when changing editor tabs
|
||||
*/
|
||||
private static readonly imageStateCache = new LRUCache<string, ImageState>(100);
|
||||
|
||||
static create(
|
||||
container: HTMLElement,
|
||||
descriptor: IResourceDescriptor,
|
||||
fileService: IFileService,
|
||||
scrollbar: DomScrollableElement,
|
||||
delegate: ResourceViewerDelegate,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
) {
|
||||
const disposables = new DisposableStore();
|
||||
|
||||
const zoomStatusbarItem = disposables.add(instantiationService.createInstance(ZoomStatusbarItem,
|
||||
newScale => updateScale(newScale)));
|
||||
|
||||
const context: ResourceViewerContext = {
|
||||
layout(dimension: DOM.Dimension) { },
|
||||
dispose: () => disposables.dispose()
|
||||
};
|
||||
|
||||
const cacheKey = `${descriptor.resource.toString()}:${descriptor.etag}`;
|
||||
|
||||
let ctrlPressed = false;
|
||||
let altPressed = false;
|
||||
|
||||
const initialState: ImageState = InlineImageView.imageStateCache.get(cacheKey) || { scale: 'fit', offsetX: 0, offsetY: 0 };
|
||||
let scale = initialState.scale;
|
||||
let image: HTMLImageElement | null = null;
|
||||
|
||||
function updateScale(newScale: Scale) {
|
||||
if (!image || !image.parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newScale === 'fit') {
|
||||
scale = 'fit';
|
||||
DOM.addClass(image, 'scale-to-fit');
|
||||
DOM.removeClass(image, 'pixelated');
|
||||
image.style.minWidth = 'auto';
|
||||
image.style.width = 'auto';
|
||||
InlineImageView.imageStateCache.delete(cacheKey);
|
||||
} else {
|
||||
const oldWidth = image.width;
|
||||
const oldHeight = image.height;
|
||||
|
||||
scale = clamp(newScale, InlineImageView.MIN_SCALE, InlineImageView.MAX_SCALE);
|
||||
if (scale >= InlineImageView.PIXELATION_THRESHOLD) {
|
||||
DOM.addClass(image, 'pixelated');
|
||||
} else {
|
||||
DOM.removeClass(image, 'pixelated');
|
||||
}
|
||||
|
||||
const { scrollTop, scrollLeft } = image.parentElement;
|
||||
const dx = (scrollLeft + image.parentElement.clientWidth / 2) / image.parentElement.scrollWidth;
|
||||
const dy = (scrollTop + image.parentElement.clientHeight / 2) / image.parentElement.scrollHeight;
|
||||
|
||||
DOM.removeClass(image, 'scale-to-fit');
|
||||
image.style.minWidth = `${(image.naturalWidth * scale)}px`;
|
||||
image.style.width = `${(image.naturalWidth * scale)}px`;
|
||||
|
||||
const newWidth = image.width;
|
||||
const scaleFactor = (newWidth - oldWidth) / oldWidth;
|
||||
|
||||
const newScrollLeft = ((oldWidth * scaleFactor * dx) + scrollLeft);
|
||||
const newScrollTop = ((oldHeight * scaleFactor * dy) + scrollTop);
|
||||
scrollbar.setScrollPosition({
|
||||
scrollLeft: newScrollLeft,
|
||||
scrollTop: newScrollTop,
|
||||
});
|
||||
|
||||
InlineImageView.imageStateCache.set(cacheKey, { scale: scale, offsetX: newScrollLeft, offsetY: newScrollTop });
|
||||
}
|
||||
|
||||
zoomStatusbarItem.updateStatusbar(scale);
|
||||
scrollbar.scanDomNode();
|
||||
}
|
||||
|
||||
function firstZoom() {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
scale = image.clientWidth / image.naturalWidth;
|
||||
updateScale(scale);
|
||||
}
|
||||
|
||||
disposables.add(DOM.addDisposableListener(window, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
if (platform.isMacintosh ? altPressed : ctrlPressed) {
|
||||
DOM.removeClass(container, 'zoom-in');
|
||||
DOM.addClass(container, 'zoom-out');
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.add(DOM.addDisposableListener(window, DOM.EventType.KEY_UP, (e: KeyboardEvent) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
if (!(platform.isMacintosh ? altPressed : ctrlPressed)) {
|
||||
DOM.removeClass(container, 'zoom-out');
|
||||
DOM.addClass(container, 'zoom-in');
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.add(DOM.addDisposableListener(container, DOM.EventType.CLICK, (e: MouseEvent) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// left click
|
||||
if (scale === 'fit') {
|
||||
firstZoom();
|
||||
}
|
||||
|
||||
if (!(platform.isMacintosh ? altPressed : ctrlPressed)) { // zoom in
|
||||
let i = 0;
|
||||
for (; i < InlineImageView.zoomLevels.length; ++i) {
|
||||
if (InlineImageView.zoomLevels[i] > scale) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateScale(InlineImageView.zoomLevels[i] || InlineImageView.MAX_SCALE);
|
||||
} else {
|
||||
let i = InlineImageView.zoomLevels.length - 1;
|
||||
for (; i >= 0; --i) {
|
||||
if (InlineImageView.zoomLevels[i] < scale) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateScale(InlineImageView.zoomLevels[i] || InlineImageView.MIN_SCALE);
|
||||
}
|
||||
}));
|
||||
|
||||
disposables.add(DOM.addDisposableListener(container, DOM.EventType.WHEEL, (e: WheelEvent) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isScrollWheelKeyPressed = platform.isMacintosh ? altPressed : ctrlPressed;
|
||||
if (!isScrollWheelKeyPressed && !e.ctrlKey) { // pinching is reported as scroll wheel + ctrl
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (scale === 'fit') {
|
||||
firstZoom();
|
||||
}
|
||||
|
||||
let delta = e.deltaY > 0 ? 1 : -1;
|
||||
|
||||
updateScale(scale as number * (1 - delta * InlineImageView.SCALE_PINCH_FACTOR));
|
||||
}));
|
||||
|
||||
disposables.add(DOM.addDisposableListener(container, DOM.EventType.SCROLL, () => {
|
||||
if (!image || !image.parentElement || scale === 'fit') {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry = InlineImageView.imageStateCache.get(cacheKey);
|
||||
if (entry) {
|
||||
const { scrollTop, scrollLeft } = image.parentElement;
|
||||
InlineImageView.imageStateCache.set(cacheKey, { scale: entry.scale, offsetX: scrollLeft, offsetY: scrollTop });
|
||||
}
|
||||
}));
|
||||
|
||||
DOM.clearNode(container);
|
||||
DOM.addClasses(container, 'image', 'zoom-in');
|
||||
|
||||
image = DOM.append(container, DOM.$<HTMLImageElement>('img.scale-to-fit'));
|
||||
image.style.visibility = 'hidden';
|
||||
|
||||
disposables.add(DOM.addDisposableListener(image, DOM.EventType.LOAD, e => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
if (typeof descriptor.size === 'number') {
|
||||
delegate.metadataClb(nls.localize('imgMeta', '{0}x{1} {2}', image.naturalWidth, image.naturalHeight, BinarySize.formatSize(descriptor.size)));
|
||||
} else {
|
||||
delegate.metadataClb(nls.localize('imgMetaNoSize', '{0}x{1}', image.naturalWidth, image.naturalHeight));
|
||||
}
|
||||
|
||||
scrollbar.scanDomNode();
|
||||
image.style.visibility = 'visible';
|
||||
updateScale(scale);
|
||||
if (initialState.scale !== 'fit') {
|
||||
scrollbar.setScrollPosition({
|
||||
scrollLeft: initialState.offsetX,
|
||||
scrollTop: initialState.offsetY,
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
InlineImageView.imageSrc(descriptor, fileService).then(src => {
|
||||
const img = container.querySelector('img');
|
||||
if (img) {
|
||||
if (typeof src === 'string') {
|
||||
img.src = src;
|
||||
} else {
|
||||
const url = URL.createObjectURL(src);
|
||||
disposables.add(toDisposable(() => URL.revokeObjectURL(url)));
|
||||
img.src = url;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
private static async imageSrc(descriptor: IResourceDescriptor, fileService: IFileService): Promise<string | Blob> {
|
||||
if (descriptor.resource.scheme === Schemas.data) {
|
||||
return descriptor.resource.toString(true /* skip encoding */);
|
||||
}
|
||||
|
||||
const { value } = await fileService.readFile(descriptor.resource);
|
||||
return new Blob([value.buffer], { type: getMime(descriptor) });
|
||||
}
|
||||
}
|
||||
|
||||
function getMime(descriptor: IResourceDescriptor) {
|
||||
let mime: string | undefined = descriptor.mime;
|
||||
if (!mime && descriptor.resource.scheme !== Schemas.data) {
|
||||
mime = mimes.getMediaMime(descriptor.resource.path);
|
||||
}
|
||||
|
||||
return mime || mimes.MIME_BINARY;
|
||||
}
|
||||
|
||||
@@ -93,20 +93,20 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.updateStyles();
|
||||
}
|
||||
|
||||
async setInput(newInput: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
async setInput(newInput: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
const oldInput = this.input as SideBySideEditorInput;
|
||||
await super.setInput(newInput, options, token);
|
||||
|
||||
return this.updateInput(oldInput, (newInput as SideBySideEditorInput), options, token);
|
||||
}
|
||||
|
||||
setOptions(options: EditorOptions): void {
|
||||
setOptions(options: EditorOptions | undefined): void {
|
||||
if (this.masterEditor) {
|
||||
this.masterEditor.setOptions(options);
|
||||
}
|
||||
}
|
||||
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup): void {
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
|
||||
if (this.masterEditor) {
|
||||
this.masterEditor.setVisible(visible, group);
|
||||
}
|
||||
@@ -159,7 +159,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
return this.detailsEditor;
|
||||
}
|
||||
|
||||
private async updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
private async updateInput(oldInput: SideBySideEditorInput, newInput: SideBySideEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
if (!newInput.matches(oldInput)) {
|
||||
if (oldInput) {
|
||||
this.disposeEditors();
|
||||
@@ -173,12 +173,12 @@ export class SideBySideEditor extends BaseEditor {
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
this.detailsEditor.setInput(newInput.details, null, token),
|
||||
this.detailsEditor.setInput(newInput.details, undefined, token),
|
||||
this.masterEditor.setInput(newInput.master, options, token)
|
||||
]);
|
||||
}
|
||||
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
private setNewInput(newInput: SideBySideEditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
const detailsEditor = this.doCreateEditor(newInput.details, this.detailsEditorContainer);
|
||||
const masterEditor = this.doCreateEditor(newInput.master, this.masterEditorContainer);
|
||||
|
||||
@@ -198,7 +198,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
return editor;
|
||||
}
|
||||
|
||||
private async onEditorsCreated(details: BaseEditor, master: BaseEditor, detailsInput: EditorInput, masterInput: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
private async onEditorsCreated(details: BaseEditor, master: BaseEditor, detailsInput: EditorInput, masterInput: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
this.detailsEditor = details;
|
||||
this.masterEditor = master;
|
||||
|
||||
@@ -210,7 +210,7 @@ export class SideBySideEditor extends BaseEditor {
|
||||
this.onDidCreateEditors.fire(undefined);
|
||||
|
||||
await Promise.all([
|
||||
this.detailsEditor.setInput(detailsInput, null, token),
|
||||
this.detailsEditor.setInput(detailsInput, undefined, token),
|
||||
this.masterEditor.setInput(masterInput, options, token)]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { isFunction, isObject, isArray } from 'vs/base/common/types';
|
||||
import { IDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IDiffEditorOptions, IEditorOptions as ICodeEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { BaseTextEditor, IEditorConfiguration } from 'vs/workbench/browser/parts/editor/textEditor';
|
||||
@@ -31,7 +31,8 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { EditorMemento } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { IWindowService } from 'vs/platform/windows/common/windows';
|
||||
import { EditorActivation } from 'vs/platform/editor/common/editor';
|
||||
import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
|
||||
/**
|
||||
* The text editor that leverages the diff text editor for the editing experience.
|
||||
@@ -40,7 +41,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
|
||||
static readonly ID = TEXT_DIFF_EDITOR_ID;
|
||||
|
||||
private diffNavigator: DiffNavigator;
|
||||
private diffNavigator: DiffNavigator | undefined;
|
||||
private readonly diffNavigatorDisposables = this._register(new DisposableStore());
|
||||
|
||||
private reverseColor: boolean; // {{SQL CARBON EDIT}} add property
|
||||
@@ -54,7 +55,8 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IEditorGroupsService editorGroupService: IEditorGroupsService,
|
||||
@ITextFileService textFileService: ITextFileService,
|
||||
@IWindowService windowService: IWindowService
|
||||
@IWindowService windowService: IWindowService,
|
||||
@IClipboardService private _clipboardService: IClipboardService,
|
||||
) {
|
||||
super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, windowService);
|
||||
}
|
||||
@@ -63,7 +65,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
return new EditorMemento(this.getId(), key, Object.create(null), limit, editorGroupService); // do not persist in storage as diff editors are never persisted
|
||||
}
|
||||
|
||||
getTitle(): string | null {
|
||||
getTitle(): string | undefined {
|
||||
if (this.input) {
|
||||
return this.input.getName();
|
||||
}
|
||||
@@ -77,15 +79,13 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
}
|
||||
|
||||
createEditorControl(parent: HTMLElement, configuration: ICodeEditorOptions): IDiffEditor {
|
||||
// {{SQL CARBON EDIT}}
|
||||
if (this.reverseColor) {
|
||||
if (this.reverseColor) { // {{SQL CARBON EDIT}}
|
||||
(configuration as IDiffEditorOptions).reverse = true;
|
||||
}
|
||||
|
||||
return this.instantiationService.createInstance(DiffEditorWidget, parent, configuration);
|
||||
return this.instantiationService.createInstance(DiffEditorWidget, parent, configuration, this._clipboardService);
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Dispose previous diff navigator
|
||||
this.diffNavigatorDisposables.clear();
|
||||
@@ -116,7 +116,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
|
||||
// Apply Options from TextOptions
|
||||
let optionsGotApplied = false;
|
||||
if (options && types.isFunction((<TextEditorOptions>options).apply)) {
|
||||
if (options && isFunction((<TextEditorOptions>options).apply)) {
|
||||
optionsGotApplied = (<TextEditorOptions>options).apply(diffEditor, ScrollType.Immediate);
|
||||
}
|
||||
|
||||
@@ -145,9 +145,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options: EditorOptions): void {
|
||||
setOptions(options: EditorOptions | undefined): void {
|
||||
const textOptions = <TextEditorOptions>options;
|
||||
if (textOptions && types.isFunction(textOptions.apply)) {
|
||||
if (textOptions && isFunction(textOptions.apply)) {
|
||||
textOptions.apply(this.getControl(), ScrollType.Smooth);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
return false;
|
||||
}
|
||||
|
||||
private openAsBinary(input: EditorInput, options: EditorOptions): boolean {
|
||||
private openAsBinary(input: EditorInput, options: EditorOptions | undefined): boolean {
|
||||
if (input instanceof DiffEditorInput) {
|
||||
const originalInput = input.originalInput;
|
||||
const modifiedInput = input.modifiedInput;
|
||||
@@ -189,7 +189,12 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
// because we are triggering another openEditor() call
|
||||
// and do not control the initial intent that resulted
|
||||
// in us now opening as binary.
|
||||
options.overwrite({ activation: EditorActivation.PRESERVE });
|
||||
const preservingOptions: IEditorOptions = { activation: EditorActivation.PRESERVE };
|
||||
if (options) {
|
||||
options.overwrite(preservingOptions);
|
||||
} else {
|
||||
options = EditorOptions.create(preservingOptions);
|
||||
}
|
||||
|
||||
this.editorService.openEditor(binaryDiffInput, options, this.group);
|
||||
|
||||
@@ -203,7 +208,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
const editorConfiguration = super.computeConfiguration(configuration);
|
||||
|
||||
// Handle diff editor specially by merging in diffEditor configuration
|
||||
if (types.isObject(configuration.diffEditor)) {
|
||||
if (isObject(configuration.diffEditor)) {
|
||||
objects.mixin(editorConfiguration, configuration.diffEditor);
|
||||
}
|
||||
|
||||
@@ -245,7 +250,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
private isFileBinaryError(error: Error[]): boolean;
|
||||
private isFileBinaryError(error: Error): boolean;
|
||||
private isFileBinaryError(error: Error | Error[]): boolean {
|
||||
if (types.isArray(error)) {
|
||||
if (isArray(error)) {
|
||||
const errors = <Error[]>error;
|
||||
|
||||
return errors.some(e => this.isFileBinaryError(e));
|
||||
@@ -269,7 +274,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
super.clearInput();
|
||||
}
|
||||
|
||||
getDiffNavigator(): DiffNavigator {
|
||||
getDiffNavigator(): DiffNavigator | undefined {
|
||||
return this.diffNavigator;
|
||||
}
|
||||
|
||||
@@ -281,7 +286,7 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
|
||||
return super.loadTextEditorViewState(resource) as IDiffEditorViewState; // overridden for text diff editor support
|
||||
}
|
||||
|
||||
private saveTextDiffEditorViewState(input: EditorInput | null): void {
|
||||
private saveTextDiffEditorViewState(input: EditorInput | undefined): void {
|
||||
if (!(input instanceof DiffEditorInput)) {
|
||||
return; // only supported for diff editor inputs
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface IEditorConfiguration {
|
||||
export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
private editorControl: IEditor;
|
||||
private _editorContainer: HTMLElement;
|
||||
private hasPendingConfigurationChange: boolean;
|
||||
private hasPendingConfigurationChange: boolean | undefined;
|
||||
private lastAppliedEditorOptions?: IEditorOptions;
|
||||
private editorMemento: IEditorMemento<IEditorViewState>;
|
||||
|
||||
@@ -191,7 +191,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
return this.instantiationService.createInstance(CodeEditorWidget, parent, configuration, {});
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
await super.setInput(input, options, token);
|
||||
|
||||
// Update editor options after having set the input. We do this because there can be
|
||||
@@ -200,7 +200,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
|
||||
this._editorContainer.setAttribute('aria-label', this.computeAriaLabel());
|
||||
}
|
||||
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup): void {
|
||||
protected setEditorVisible(visible: boolean, group: IEditorGroup | undefined): void {
|
||||
|
||||
// Pass on to Editor
|
||||
if (visible) {
|
||||
|
||||
@@ -46,7 +46,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, windowService);
|
||||
}
|
||||
|
||||
getTitle(): string | null {
|
||||
getTitle(): string | undefined {
|
||||
if (this.input) {
|
||||
return this.input.getName();
|
||||
}
|
||||
@@ -54,7 +54,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
return nls.localize('textEditor', "Text Editor");
|
||||
}
|
||||
|
||||
async setInput(input: EditorInput, options: EditorOptions, token: CancellationToken): Promise<void> {
|
||||
async setInput(input: EditorInput, options: EditorOptions | undefined, token: CancellationToken): Promise<void> {
|
||||
|
||||
// Remember view settings if input changes
|
||||
this.saveTextResourceEditorViewState(this.input);
|
||||
@@ -100,7 +100,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
}
|
||||
}
|
||||
|
||||
setOptions(options: EditorOptions): void {
|
||||
setOptions(options: EditorOptions | undefined): void {
|
||||
const textOptions = <TextEditorOptions>options;
|
||||
if (textOptions && types.isFunction(textOptions.apply)) {
|
||||
textOptions.apply(this.getControl(), ScrollType.Smooth);
|
||||
@@ -164,7 +164,7 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
|
||||
super.saveState();
|
||||
}
|
||||
|
||||
private saveTextResourceEditorViewState(input: EditorInput | null): void {
|
||||
private saveTextResourceEditorViewState(input: EditorInput | undefined): void {
|
||||
if (!(input instanceof UntitledEditorInput) && !(input instanceof ResourceEditorInput)) {
|
||||
return; // only enabled for untitled and resource inputs
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ export abstract class TitleControl extends Themable {
|
||||
private currentPrimaryEditorActionIds: string[] = [];
|
||||
private currentSecondaryEditorActionIds: string[] = [];
|
||||
|
||||
protected editorActionsToolbar: ToolBar;
|
||||
private editorActionsToolbar: ToolBar;
|
||||
|
||||
private resourceContext: ResourceContextKey;
|
||||
private editorPinnedContext: IContextKey<boolean>;
|
||||
@@ -275,7 +275,7 @@ export abstract class TitleControl extends Themable {
|
||||
label = localize('draggedEditorGroup', "{0} (+{1})", label, this.group.count - 1);
|
||||
}
|
||||
|
||||
applyDragImage(e, label, 'monaco-editor-group-drag-image');
|
||||
applyDragImage(e, withUndefinedAsNull(label), 'monaco-editor-group-drag-image');
|
||||
}
|
||||
}));
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export class NotificationsList extends Themable {
|
||||
private listContainer: HTMLElement;
|
||||
private list: WorkbenchList<INotificationViewItem>;
|
||||
private viewModel: INotificationViewItem[];
|
||||
private isVisible: boolean;
|
||||
private isVisible: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
private container: HTMLElement,
|
||||
@@ -72,6 +72,7 @@ export class NotificationsList extends Themable {
|
||||
// List
|
||||
this.list = this._register(this.instantiationService.createInstance(
|
||||
WorkbenchList,
|
||||
'NotificationsList',
|
||||
this.listContainer,
|
||||
new NotificationsListDelegate(this.listContainer),
|
||||
[renderer],
|
||||
|
||||
@@ -54,7 +54,7 @@ export class NotificationsToasts extends Themable {
|
||||
|
||||
private notificationsToastsContainer: HTMLElement;
|
||||
private workbenchDimensions: Dimension;
|
||||
private isNotificationsCenterVisible: boolean;
|
||||
private isNotificationsCenterVisible: boolean | undefined;
|
||||
private mapNotificationToToast: Map<INotificationViewItem, INotificationToast>;
|
||||
private notificationsToastsVisibleContextKey: IContextKey<boolean>;
|
||||
|
||||
@@ -236,12 +236,11 @@ export class NotificationsToasts extends Themable {
|
||||
|
||||
purgeTimeoutHandle = setTimeout(() => {
|
||||
|
||||
// If the notification is sticky or prompting and the window does not have
|
||||
// focus, we wait for the window to gain focus again before triggering
|
||||
// the timeout again. This prevents an issue where focussing the window
|
||||
// could immediately hide the notification because the timeout was triggered
|
||||
// again.
|
||||
if ((item.sticky || item.hasPrompt()) && !this.windowService.hasFocus) {
|
||||
// If the window does not have focus, we wait for the window to gain focus
|
||||
// again before triggering the timeout again. This prevents an issue where
|
||||
// focussing the window could immediately hide the notification because the
|
||||
// timeout was triggered again.
|
||||
if (!this.windowService.hasFocus) {
|
||||
if (!listener) {
|
||||
listener = this.windowService.onDidChangeFocus(focus => {
|
||||
if (focus) {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
}
|
||||
|
||||
.monaco-workbench .part.panel .title {
|
||||
padding-right: 0px;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -17,7 +17,7 @@ import { IStorageService, StorageScope, IWorkspaceStorageChangeEvent } from 'vs/
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ClosePanelAction, TogglePanelPositionAction, PanelActivityAction, ToggleMaximizedPanelAction, TogglePanelAction } from 'vs/workbench/browser/parts/panel/panelActions';
|
||||
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { PANEL_BACKGROUND, PANEL_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND, PANEL_ACTIVE_TITLE_BORDER, PANEL_DRAG_AND_DROP_BACKGROUND, PANEL_INPUT_BORDER } from 'vs/workbench/common/theme';
|
||||
@@ -48,7 +48,7 @@ export class PanelPart extends CompositePart<Panel> implements IPanelService {
|
||||
private static readonly PINNED_PANELS = 'workbench.panel.pinnedPanels';
|
||||
private static readonly MIN_COMPOSITE_BAR_WIDTH = 50;
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
//#region IView
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { Component } from 'vs/workbench/common/component';
|
||||
import { IQuickInputService, IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { contrastBorder, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { QUICK_INPUT_BACKGROUND, QUICK_INPUT_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
@@ -44,6 +44,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { registerAndGetAmdImageURL } from 'vs/base/common/amd';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -51,8 +52,8 @@ type Writeable<T> = { -readonly [P in keyof T]: T[P] };
|
||||
|
||||
const backButton = {
|
||||
iconPath: {
|
||||
dark: URI.parse(require.toUrl('vs/workbench/browser/parts/quickinput/media/arrow-left-dark.svg')),
|
||||
light: URI.parse(require.toUrl('vs/workbench/browser/parts/quickinput/media/arrow-left-light.svg'))
|
||||
dark: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/quickinput/media/arrow-left-dark.svg')),
|
||||
light: URI.parse(registerAndGetAmdImageURL('vs/workbench/browser/parts/quickinput/media/arrow-left-light.svg'))
|
||||
},
|
||||
tooltip: localize('quickInput.back', "Back"),
|
||||
handle: -1 // TODO
|
||||
@@ -880,7 +881,7 @@ class InputBox extends QuickInput implements IInputBox {
|
||||
|
||||
export class QuickInputService extends Component implements IQuickInputService {
|
||||
|
||||
public _serviceBrand!: ServiceIdentifier<any>;
|
||||
public _serviceBrand: undefined;
|
||||
|
||||
private static readonly ID = 'workbench.component.quickinput';
|
||||
private static readonly MAX_WIDTH = 600; // Max total width of quick open widget
|
||||
|
||||
@@ -246,7 +246,7 @@ export class QuickInputList {
|
||||
this.id = id;
|
||||
this.container = dom.append(this.parent, $('.quick-input-list'));
|
||||
const delegate = new ListElementDelegate();
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, this.container, delegate, [new ListElementRenderer()], {
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, 'QuickInput', this.container, delegate, [new ListElementRenderer()], {
|
||||
identityProvider: { getId: element => element.saneLabel },
|
||||
openController: { shouldOpen: () => false }, // Workaround #58124
|
||||
setRowLineHeight: false,
|
||||
|
||||
@@ -30,7 +30,7 @@ import { QuickOpenHandler, QuickOpenHandlerDescriptor, IQuickOpenRegistry, Exten
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { IQuickOpenService, IShowOptions } from 'vs/platform/quickOpen/common/quickOpen';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -61,7 +61,7 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
private static readonly MAX_SHORT_RESPONSE_TIME = 500;
|
||||
private static readonly ID = 'workbench.component.quickopen';
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly _onShow: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onShow: Event<void> = this._onShow.event;
|
||||
@@ -183,10 +183,10 @@ export class QuickOpenController extends Component implements IQuickOpenService
|
||||
onHide: (reason) => this.handleOnHide(reason),
|
||||
onFocusLost: () => !this.closeOnFocusLost
|
||||
}, {
|
||||
inputPlaceHolder: this.hasHandler(HELP_PREFIX) ? nls.localize('quickOpenInput', "Type '?' to get help on the actions you can take from here") : '',
|
||||
keyboardSupport: false,
|
||||
treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts)
|
||||
}
|
||||
inputPlaceHolder: this.hasHandler(HELP_PREFIX) ? nls.localize('quickOpenInput', "Type '?' to get help on the actions you can take from here") : '',
|
||||
keyboardSupport: false,
|
||||
treeCreator: (container, config, opts) => this.instantiationService.createInstance(WorkbenchTree, container, config, opts)
|
||||
}
|
||||
));
|
||||
this._register(attachQuickOpenStyler(this.quickOpenWidget, this.themeService, { background: QUICK_INPUT_BACKGROUND, foreground: QUICK_INPUT_FOREGROUND }));
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
@@ -35,7 +35,7 @@ import { LayoutPriority } from 'vs/base/browser/ui/grid/grid';
|
||||
|
||||
export class SidebarPart extends CompositePart<Viewlet> implements IViewletService {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
static readonly activeViewletSettingsKey = 'workbench.sidebar.activeviewletid';
|
||||
|
||||
|
||||
@@ -12,6 +12,18 @@
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.statusbar.status-border-top::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 5;
|
||||
pointer-events: none;
|
||||
background-color: var(--status-border-top-color);
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.monaco-workbench .part.statusbar > .left-items,
|
||||
.monaco-workbench .part.statusbar > .right-items {
|
||||
display: flex;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { OcticonLabel } from 'vs/base/browser/ui/octiconLabel/octiconLabel';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { StatusbarAlignment, IStatusbarService, IStatusbarEntry, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
@@ -57,7 +57,7 @@ class StatusbarViewModel extends Disposable {
|
||||
private readonly _entries: IStatusbarViewModelEntry[] = [];
|
||||
get entries(): IStatusbarViewModelEntry[] { return this._entries; }
|
||||
|
||||
private hidden: Set<string>;
|
||||
private hidden!: Set<string>;
|
||||
|
||||
constructor(private storageService: IStorageService) {
|
||||
super();
|
||||
@@ -323,7 +323,7 @@ class HideStatusbarEntryAction extends Action {
|
||||
|
||||
export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<IStatusbarService>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
//#region IView
|
||||
|
||||
@@ -334,14 +334,14 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
//#endregion
|
||||
|
||||
private styleElement: HTMLStyleElement;
|
||||
private styleElement!: HTMLStyleElement;
|
||||
|
||||
private pendingEntries: IPendingStatusbarEntry[] = [];
|
||||
|
||||
private readonly viewModel: StatusbarViewModel;
|
||||
|
||||
private leftItemsContainer: HTMLElement;
|
||||
private rightItemsContainer: HTMLElement;
|
||||
private leftItemsContainer!: HTMLElement;
|
||||
private rightItemsContainer!: HTMLElement;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@@ -580,9 +580,13 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
// Border color
|
||||
const borderColor = this.getColor(this.contextService.getWorkbenchState() !== WorkbenchState.EMPTY ? STATUS_BAR_BORDER : STATUS_BAR_NO_FOLDER_BORDER) || this.getColor(contrastBorder);
|
||||
container.style.borderTopWidth = borderColor ? '1px' : null;
|
||||
container.style.borderTopStyle = borderColor ? 'solid' : null;
|
||||
container.style.borderTopColor = borderColor;
|
||||
if (borderColor) {
|
||||
addClass(container, 'status-border-top');
|
||||
container.style.setProperty('--status-border-top-color', borderColor.toString());
|
||||
} else {
|
||||
removeClass(container, 'status-border-top');
|
||||
container.style.removeProperty('--status-border-top-color');
|
||||
}
|
||||
|
||||
// Notification Beak
|
||||
if (!this.styleElement) {
|
||||
@@ -623,10 +627,10 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
}
|
||||
|
||||
class StatusbarEntryItem extends Disposable {
|
||||
private entry: IStatusbarEntry;
|
||||
private entry!: IStatusbarEntry;
|
||||
|
||||
private labelContainer: HTMLElement;
|
||||
private label: OcticonLabel;
|
||||
private labelContainer!: HTMLElement;
|
||||
private label!: OcticonLabel;
|
||||
|
||||
private readonly foregroundListener = this._register(new MutableDisposable());
|
||||
private readonly backgroundListener = this._register(new MutableDisposable());
|
||||
|
||||
@@ -254,6 +254,7 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
private menubar: MenuBar;
|
||||
private container: HTMLElement;
|
||||
private alwaysOnMnemonics: boolean;
|
||||
private focusInsideMenubar: boolean;
|
||||
|
||||
private readonly _onVisibilityChange: Emitter<boolean>;
|
||||
private readonly _onFocusStateChange: Emitter<boolean>;
|
||||
@@ -469,11 +470,11 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
if (firstTime) {
|
||||
this.menubar = this._register(new MenuBar(
|
||||
this.container, {
|
||||
enableMnemonics: this.currentEnableMenuBarMnemonics,
|
||||
disableAltFocus: this.currentDisableMenuBarAltFocus,
|
||||
visibility: this.currentMenubarVisibility,
|
||||
getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id),
|
||||
}
|
||||
enableMnemonics: this.currentEnableMenuBarMnemonics,
|
||||
disableAltFocus: this.currentDisableMenuBarAltFocus,
|
||||
visibility: this.currentMenubarVisibility,
|
||||
getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id),
|
||||
}
|
||||
));
|
||||
|
||||
this.accessibilityService.alwaysUnderlineAccessKeys().then(val => {
|
||||
@@ -481,9 +482,27 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics });
|
||||
});
|
||||
|
||||
this._register(this.menubar.onFocusStateChange(e => this._onFocusStateChange.fire(e)));
|
||||
this._register(this.menubar.onFocusStateChange(focused => {
|
||||
this._onFocusStateChange.fire(focused);
|
||||
|
||||
// When the menubar loses focus, update it to clear any pending updates
|
||||
if (!focused) {
|
||||
this.updateMenubar();
|
||||
this.focusInsideMenubar = false;
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(this.menubar.onVisibilityChange(e => this._onVisibilityChange.fire(e)));
|
||||
|
||||
// Before we focus the menubar, stop updates to it so that focus-related context keys will work
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_IN, () => {
|
||||
this.focusInsideMenubar = true;
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this.container, DOM.EventType.FOCUS_OUT, () => {
|
||||
this.focusInsideMenubar = false;
|
||||
}));
|
||||
|
||||
this._register(attachMenuStyler(this.menubar, this.themeService));
|
||||
} else {
|
||||
this.menubar.update({ enableMnemonics: this.currentEnableMenuBarMnemonics, disableAltFocus: this.currentDisableMenuBarAltFocus, visibility: this.currentMenubarVisibility, getKeybinding: (action) => this.keybindingService.lookupKeybinding(action.id), alwaysOnMnemonics: this.alwaysOnMnemonics });
|
||||
@@ -503,9 +522,11 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
this.menus[action.item.submenu] = this.menuService.createMenu(action.item.submenu, this.contextKeyService);
|
||||
const submenu = this.menus[action.item.submenu];
|
||||
this._register(submenu!.onDidChange(() => {
|
||||
const actions: IAction[] = [];
|
||||
updateActions(menu, actions, topLevelTitle);
|
||||
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
|
||||
if (!this.focusInsideMenubar) {
|
||||
const actions: IAction[] = [];
|
||||
updateActions(menu, actions, topLevelTitle);
|
||||
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[topLevelTitle]) });
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
|
||||
@@ -529,9 +550,11 @@ export class CustomMenubarControl extends MenubarControl {
|
||||
const menu = this.menus[title];
|
||||
if (firstTime && menu) {
|
||||
this._register(menu.onDidChange(() => {
|
||||
const actions: IAction[] = [];
|
||||
updateActions(menu, actions, title);
|
||||
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
|
||||
if (!this.focusInsideMenubar) {
|
||||
const actions: IAction[] = [];
|
||||
updateActions(menu, actions, title);
|
||||
this.menubar.updateMenu({ actions: actions, label: mnemonicMenuLabel(this.topLevelTitles[title]) });
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { Color } from 'vs/base/common/color';
|
||||
import { trim } from 'vs/base/common/strings';
|
||||
import { EventType, EventHelper, Dimension, isAncestor, hide, show, removeClass, addClass, append, $, addDisposableListener, runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { CustomMenubarControl } from 'vs/workbench/browser/parts/titlebar/menubarControl';
|
||||
import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { template, getBaseLabel } from 'vs/base/common/labels';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
@@ -58,7 +58,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
private _onMenubarVisibilityChange = this._register(new Emitter<boolean>());
|
||||
readonly onMenubarVisibilityChange: Event<boolean> = this._onMenubarVisibilityChange.event;
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private title: HTMLElement;
|
||||
private dragRegion: HTMLElement;
|
||||
@@ -554,7 +554,7 @@ export class TitlebarPart extends Part implements ITitleService {
|
||||
rightMarker < (this.element.clientWidth + this.title.clientWidth) / 2) {
|
||||
this.title.style.position = null;
|
||||
this.title.style.left = null;
|
||||
this.title.style.transform = null;
|
||||
this.title.style.transform = '';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ export class CustomTreeViewPanel extends ViewletPanel {
|
||||
const { treeView } = (<ITreeViewDescriptor>Registry.as<IViewsRegistry>(Extensions.ViewsRegistry).getView(options.id));
|
||||
this.treeView = treeView;
|
||||
this._register(this.treeView.onDidChangeActions(() => this.updateActions(), this));
|
||||
this._register(this.treeView.onDidChangeTitle((newTitle) => this.updateTitle(newTitle)));
|
||||
this._register(toDisposable(() => this.treeView.setVisibility(false)));
|
||||
this._register(this.onDidChangeBodyVisibility(() => this.updateTreeVisibility()));
|
||||
this.updateTreeVisibility();
|
||||
@@ -190,9 +191,12 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
private readonly _onDidChangeActions: Emitter<void> = this._register(new Emitter<void>());
|
||||
readonly onDidChangeActions: Event<void> = this._onDidChangeActions.event;
|
||||
|
||||
private readonly _onDidChangeTitle: Emitter<string> = this._register(new Emitter<string>());
|
||||
readonly onDidChangeTitle: Event<string> = this._onDidChangeTitle.event;
|
||||
|
||||
constructor(
|
||||
private id: string,
|
||||
private title: string,
|
||||
private _title: string,
|
||||
private viewContainer: ViewContainer,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IWorkbenchThemeService private readonly themeService: IWorkbenchThemeService,
|
||||
@@ -201,7 +205,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IProgressService private readonly progressService: IProgressService,
|
||||
@IContextMenuService private readonly contextMenuService: IContextMenuService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService,
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
this.root = new Root();
|
||||
@@ -228,6 +233,10 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
}
|
||||
|
||||
set dataProvider(dataProvider: ITreeViewDataProvider | undefined) {
|
||||
if (this.tree === undefined) {
|
||||
this.createTree();
|
||||
}
|
||||
|
||||
if (dataProvider) {
|
||||
this._dataProvider = new class implements ITreeViewDataProvider {
|
||||
async getChildren(node: ITreeItem): Promise<ITreeItem[]> {
|
||||
@@ -257,6 +266,15 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
this.updateMessage();
|
||||
}
|
||||
|
||||
get title(): string {
|
||||
return this._title;
|
||||
}
|
||||
|
||||
set title(name: string) {
|
||||
this._title = name;
|
||||
this._onDidChangeTitle.fire(this._title);
|
||||
}
|
||||
|
||||
get canSelectMany(): boolean {
|
||||
return this._canSelectMany;
|
||||
}
|
||||
@@ -366,28 +384,28 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
const aligner = new Aligner(this.themeService);
|
||||
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, treeMenus, this.treeLabels, actionViewItemProvider, aligner);
|
||||
|
||||
this.tree = this._register(this.instantiationService.createInstance(WorkbenchAsyncDataTree, this.treeContainer, new CustomTreeDelegate(), [renderer],
|
||||
this.tree = this._register(this.instantiationService.createInstance(WorkbenchAsyncDataTree, 'CustomView', this.treeContainer, new CustomTreeDelegate(), [renderer],
|
||||
dataSource, {
|
||||
identityProvider: new CustomViewIdentityProvider(),
|
||||
accessibilityProvider: {
|
||||
getAriaLabel(element: ITreeItem): string {
|
||||
return element.label ? element.label.label : '';
|
||||
}
|
||||
},
|
||||
ariaLabel: this.title,
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: (item: ITreeItem) => {
|
||||
return item.label ? item.label.label : (item.resourceUri ? basename(URI.revive(item.resourceUri)) : undefined);
|
||||
}
|
||||
},
|
||||
expandOnlyOnTwistieClick: (e: ITreeItem) => !!e.command,
|
||||
collapseByDefault: (e: ITreeItem): boolean => {
|
||||
return e.collapsibleState !== TreeItemCollapsibleState.Expanded;
|
||||
},
|
||||
multipleSelectionSupport: this.canSelectMany,
|
||||
}) as WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>);
|
||||
identityProvider: new CustomViewIdentityProvider(),
|
||||
accessibilityProvider: {
|
||||
getAriaLabel(element: ITreeItem): string {
|
||||
return element.tooltip ? element.tooltip : element.label ? element.label.label : '';
|
||||
}
|
||||
},
|
||||
ariaLabel: this._title,
|
||||
keyboardNavigationLabelProvider: {
|
||||
getKeyboardNavigationLabel: (item: ITreeItem) => {
|
||||
return item.label ? item.label.label : (item.resourceUri ? basename(URI.revive(item.resourceUri)) : undefined);
|
||||
}
|
||||
},
|
||||
expandOnlyOnTwistieClick: (e: ITreeItem) => !!e.command,
|
||||
collapseByDefault: (e: ITreeItem): boolean => {
|
||||
return e.collapsibleState !== TreeItemCollapsibleState.Expanded;
|
||||
},
|
||||
multipleSelectionSupport: this.canSelectMany,
|
||||
}) as WorkbenchAsyncDataTree<ITreeItem, ITreeItem, FuzzyScore>);
|
||||
aligner.tree = this.tree;
|
||||
const actionRunner = new MultipleSelectionActionRunner(() => this.tree!.getSelection());
|
||||
const actionRunner = new MultipleSelectionActionRunner(this.notificationService, () => this.tree!.getSelection());
|
||||
renderer.actionRunner = actionRunner;
|
||||
|
||||
this.tree.contextKeyService.createKey<boolean>(this.id, true);
|
||||
@@ -578,7 +596,6 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
|
||||
private activate() {
|
||||
if (!this.activated) {
|
||||
this.createTree();
|
||||
this.progressService.withProgress({ location: this.viewContainer.id }, () => this.extensionService.activateByEvent(`onView:${this.id}`))
|
||||
.then(() => timeout(2000))
|
||||
.then(() => {
|
||||
@@ -593,16 +610,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
||||
const tree = this.tree;
|
||||
if (tree) {
|
||||
this.refreshing = true;
|
||||
const parents: Set<ITreeItem> = new Set<ITreeItem>();
|
||||
elements.forEach(element => {
|
||||
if (element !== this.root) {
|
||||
const parent = tree.getParentElement(element);
|
||||
parents.add(parent);
|
||||
} else {
|
||||
parents.add(element);
|
||||
}
|
||||
});
|
||||
await Promise.all(Array.from(parents.values()).map(element => tree.updateChildren(element, true)));
|
||||
await Promise.all(elements.map(element => tree.updateChildren(element, true)));
|
||||
elements.map(element => tree.rerender(element));
|
||||
this.refreshing = false;
|
||||
this.updateContentAreas();
|
||||
if (this.focused) {
|
||||
@@ -845,22 +854,32 @@ class Aligner extends Disposable {
|
||||
|
||||
class MultipleSelectionActionRunner extends ActionRunner {
|
||||
|
||||
constructor(private getSelectedResources: (() => ITreeItem[])) {
|
||||
constructor(notificationService: INotificationService, private getSelectedResources: (() => ITreeItem[])) {
|
||||
super();
|
||||
this._register(this.onDidRun(e => {
|
||||
if (e.error) {
|
||||
notificationService.error(localize('command-error', 'Error running command {1}: {0}. This is likely caused by the extension that contributes {1}.', e.error.message, e.action.id));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
runAction(action: IAction, context: TreeViewItemHandleArg): Promise<any> {
|
||||
const selection = this.getSelectedResources();
|
||||
let selectionHandleArgs: TreeViewItemHandleArg[] | undefined = undefined;
|
||||
let actionInSelected: boolean = false;
|
||||
if (selection.length > 1) {
|
||||
selectionHandleArgs = [];
|
||||
selection.forEach(selected => {
|
||||
if (selected.handle !== context.$treeItemHandle) {
|
||||
selectionHandleArgs!.push({ $treeViewId: context.$treeViewId, $treeItemHandle: selected.handle });
|
||||
selectionHandleArgs = selection.map(selected => {
|
||||
if (selected.handle === context.$treeItemHandle) {
|
||||
actionInSelected = true;
|
||||
}
|
||||
return { $treeViewId: context.$treeViewId, $treeItemHandle: selected.handle };
|
||||
});
|
||||
}
|
||||
|
||||
if (!actionInSelected) {
|
||||
selectionHandleArgs = undefined;
|
||||
}
|
||||
|
||||
return action.run(...[context, selectionHandleArgs]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/co
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { toggleClass, addClass } from 'vs/base/browser/dom';
|
||||
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
|
||||
function filterViewRegisterEvent(container: ViewContainer, event: Event<{ viewContainer: ViewContainer, views: IViewDescriptor[] }>): Event<IViewDescriptor[]> {
|
||||
@@ -382,7 +381,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (this.getViewOrder(a) - this.getViewOrder(b)) || this.getGroupOrderResult(a, b) || (a.id < b.id ? -1 : 1);
|
||||
return (this.getViewOrder(a) - this.getViewOrder(b)) || this.getGroupOrderResult(a, b);
|
||||
}
|
||||
|
||||
private getGroupOrderResult(a: IViewDescriptor, b: IViewDescriptor) {
|
||||
@@ -434,7 +433,7 @@ export class ContributableViewsModel extends Disposable {
|
||||
const splices = sortedDiff<IViewDescriptor>(
|
||||
this.viewDescriptors,
|
||||
viewDescriptors,
|
||||
this.compareViewDescriptors.bind(this)
|
||||
(a, b) => a.id === b.id ? 0 : a.id < b.id ? -1 : 1
|
||||
).reverse();
|
||||
|
||||
const toRemove: { index: number, viewDescriptor: IViewDescriptor }[] = [];
|
||||
@@ -522,9 +521,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
}
|
||||
|
||||
private saveWorkspaceViewsStates(): void {
|
||||
const storedViewsStates: { [id: string]: IStoredWorkspaceViewState } = {};
|
||||
|
||||
let hasState = false;
|
||||
const storedViewsStates: { [id: string]: IStoredWorkspaceViewState } = JSON.parse(this.storageService.get(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE, '{}'));
|
||||
for (const viewDescriptor of this.viewDescriptors) {
|
||||
const viewState = this.viewStates.get(viewDescriptor.id);
|
||||
if (viewState) {
|
||||
@@ -534,11 +531,10 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
size: viewState.size,
|
||||
order: viewDescriptor.workspace && viewState ? viewState.order : undefined
|
||||
};
|
||||
hasState = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasState) {
|
||||
if (Object.keys(storedViewsStates).length > 0) {
|
||||
this.storageService.store(this.workspaceViewsStateStorageId, JSON.stringify(storedViewsStates), StorageScope.WORKSPACE);
|
||||
} else {
|
||||
this.storageService.remove(this.workspaceViewsStateStorageId, StorageScope.WORKSPACE);
|
||||
@@ -638,7 +634,7 @@ export class PersistentContributableViewsModel extends ContributableViewsModel {
|
||||
|
||||
export class ViewsService extends Disposable implements IViewsService {
|
||||
|
||||
_serviceBrand!: ServiceIdentifier<any>;
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private readonly viewDescriptorCollections: Map<ViewContainer, { viewDescriptorCollection: IViewDescriptorCollection, disposable: IDisposable }>;
|
||||
private readonly viewDisposable: Map<IViewDescriptor, IDisposable>;
|
||||
|
||||
@@ -39,7 +39,7 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
|
||||
|
||||
private readonly viewletState: MementoObject;
|
||||
private didLayout = false;
|
||||
private dimension: DOM.Dimension;
|
||||
private dimension: DOM.Dimension | undefined;
|
||||
private areExtensionsReady: boolean = false;
|
||||
|
||||
private readonly visibleViewsCountFromCache: number | undefined;
|
||||
|
||||
Reference in New Issue
Block a user