diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts index be57658a338..187ee4870c8 100644 --- a/src/vs/workbench/browser/layout.ts +++ b/src/vs/workbench/browser/layout.ts @@ -21,7 +21,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { ITitleService } from 'vs/workbench/services/title/common/titleService'; -import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; +import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { LifecyclePhase, StartupKind, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle'; import { MenuBarVisibility, getTitleBarStyle } from 'vs/platform/windows/common/windows'; import { IHostService } from 'vs/workbench/services/host/browser/host'; @@ -48,7 +48,6 @@ enum Settings { PANEL_POSITION = 'workbench.panel.defaultLocation', ZEN_MODE_RESTORE = 'zenMode.restore', - } enum Storage { @@ -105,7 +104,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi //#endregion - private _dimension: IDimension; + private _dimension!: IDimension; get dimension(): IDimension { return this._dimension; } private _container: HTMLElement = document.createElement('div'); @@ -113,30 +112,30 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi private parts: Map = new Map(); - private workbenchGrid: SerializableGrid; + private workbenchGrid!: SerializableGrid; - private disposed: boolean; + private disposed: boolean | undefined; - private titleBarPartView: ISerializableView; - private activityBarPartView: ISerializableView; - private sideBarPartView: ISerializableView; - private panelPartView: ISerializableView; - private editorPartView: ISerializableView; - private statusBarPartView: ISerializableView; + private titleBarPartView!: ISerializableView; + private activityBarPartView!: ISerializableView; + private sideBarPartView!: ISerializableView; + private panelPartView!: ISerializableView; + private editorPartView!: ISerializableView; + private statusBarPartView!: ISerializableView; - private environmentService: IWorkbenchEnvironmentService; - private configurationService: IConfigurationService; - private lifecycleService: ILifecycleService; - private storageService: IStorageService; - private hostService: IHostService; - private editorService: IEditorService; - private editorGroupService: IEditorGroupsService; - private panelService: IPanelService; - private titleService: ITitleService; - private viewletService: IViewletService; - private contextService: IWorkspaceContextService; - private backupFileService: IBackupFileService; - private notificationService: INotificationService; + private environmentService!: IWorkbenchEnvironmentService; + private configurationService!: IConfigurationService; + private lifecycleService!: ILifecycleService; + private storageService!: IStorageService; + private hostService!: IHostService; + private editorService!: IEditorService; + private editorGroupService!: IEditorGroupsService; + private panelService!: IPanelService; + private titleService!: ITitleService; + private viewletService!: IViewletService; + private contextService!: IWorkspaceContextService; + private backupFileService!: IBackupFileService; + private notificationService!: INotificationService; protected readonly state = { fullscreen: false, @@ -763,7 +762,7 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi this.workbenchGrid.setViewVisible(this.statusBarPartView, !hidden); } - protected createWorkbenchLayout(instantiationService: IInstantiationService): void { + protected createWorkbenchLayout(): void { const titleBar = this.getPart(Parts.TITLEBAR_PART); const editorPart = this.getPart(Parts.EDITOR_PART); const activityBar = this.getPart(Parts.ACTIVITYBAR_PART); diff --git a/src/vs/workbench/browser/part.ts b/src/vs/workbench/browser/part.ts index 241d86e34ac..aa36e60b373 100644 --- a/src/vs/workbench/browser/part.ts +++ b/src/vs/workbench/browser/part.ts @@ -127,7 +127,7 @@ export abstract class Part extends Component implements ISerializableView { private _onDidChange = this._register(new Emitter()); get onDidChange(): Event { return this._onDidChange.event; } - element: HTMLElement; + element!: HTMLElement; abstract minimumWidth: number; abstract maximumWidth: number; diff --git a/src/vs/workbench/browser/parts/compositeBarActions.ts b/src/vs/workbench/browser/parts/compositeBarActions.ts index 88f5a78a1da..e910ee428ea 100644 --- a/src/vs/workbench/browser/parts/compositeBarActions.ts +++ b/src/vs/workbench/browser/parts/compositeBarActions.ts @@ -126,10 +126,10 @@ export interface IActivityActionViewItemOptions extends IBaseActionViewItemOptio } export class ActivityActionViewItem extends BaseActionViewItem { - protected container: HTMLElement; - protected label: HTMLElement; - protected badge: HTMLElement; - protected options: IActivityActionViewItemOptions; + protected container!: HTMLElement; + protected label!: HTMLElement; + protected badge!: HTMLElement; + protected options!: IActivityActionViewItemOptions; private badgeContent: HTMLElement | undefined; private readonly badgeDisposable = this._register(new MutableDisposable()); @@ -219,7 +219,6 @@ export class ActivityActionViewItem extends BaseActionViewItem { dom.append(container, dom.$('.active-item-indicator')); } - dom.hide(this.badge); this.updateActivity(); @@ -303,14 +302,17 @@ export class ActivityActionViewItem extends BaseActionViewItem { } else { title = this.activity.name; } + this.updateTitle(title); } protected updateLabel(): void { this.label.className = 'action-label'; + if (this.activity.cssClass) { dom.addClass(this.label, this.activity.cssClass); } + if (!this.options.icon) { this.label.textContent = this.getAction().label; } diff --git a/src/vs/workbench/browser/parts/editor/editorPart.ts b/src/vs/workbench/browser/parts/editor/editorPart.ts index 9f5b31c4f55..20392c4f0bd 100644 --- a/src/vs/workbench/browser/parts/editor/editorPart.ts +++ b/src/vs/workbench/browser/parts/editor/editorPart.ts @@ -30,6 +30,7 @@ import { onUnexpectedError } from 'vs/base/common/errors'; import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { MementoObject } from 'vs/workbench/common/memento'; +import { assertIsDefined } from 'vs/base/common/types'; interface IEditorPartUIState { serializedGrid: ISerializedGrid; @@ -49,13 +50,13 @@ class GridWidgetView implements IView { private _onDidChange = new Relay<{ width: number; height: number; } | undefined>(); readonly onDidChange: Event<{ width: number; height: number; } | undefined> = this._onDidChange.event; - private _gridWidget: Grid; + private _gridWidget: Grid | undefined; - get gridWidget(): Grid { + get gridWidget(): Grid | undefined { return this._gridWidget; } - set gridWidget(grid: Grid) { + set gridWidget(grid: Grid | undefined) { this.element.innerHTML = ''; if (grid) { @@ -123,17 +124,18 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro private _partOptions: IEditorPartOptions; - private _activeGroup: IEditorGroupView; private groupViews: Map = new Map(); private mostRecentActiveGroups: GroupIdentifier[] = []; - private container: HTMLElement; - private centeredLayoutWidget: CenteredViewLayout; - private gridWidget: SerializableGrid; + private container: HTMLElement | undefined; + + private centeredLayoutWidget!: CenteredViewLayout; + + private gridWidget!: SerializableGrid; private gridWidgetView: GridWidgetView; private _whenRestored: Promise; - private whenRestoredResolve: () => void; + private whenRestoredResolve: (() => void) | undefined; constructor( @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -204,9 +206,10 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro //#region IEditorGroupsService - private _contentDimension: Dimension; + private _contentDimension!: Dimension; get contentDimension(): Dimension { return this._contentDimension; } + private _activeGroup!: IEditorGroupView; get activeGroup(): IEditorGroupView { return this._activeGroup; } @@ -463,7 +466,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } } - private shouldRestoreFocus(target: Element): boolean { + private shouldRestoreFocus(target: Element | undefined): boolean { + if (!target) { + return false; + } + const activeElement = document.activeElement; if (activeElement === document.body) { @@ -796,7 +803,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } updateStyles(): void { - this.container.style.backgroundColor = this.getColor(editorBackground) || ''; + const container = assertIsDefined(this.container); + container.style.backgroundColor = this.getColor(editorBackground) || ''; const separatorBorderStyle = { separatorBorder: this.gridSeparatorBorder, background: this.theme.getColor(EDITOR_PANE_BACKGROUND) || Color.transparent }; this.gridWidget.style(separatorBorderStyle); @@ -850,7 +858,11 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } // Signal restored - Promise.all(this.groups.map(group => group.whenRestored)).finally(() => this.whenRestoredResolve()); + Promise.all(this.groups.map(group => group.whenRestored)).finally(() => { + if (this.whenRestoredResolve) { + this.whenRestoredResolve(); + } + }); // Update container this.updateContainer(); @@ -950,7 +962,8 @@ export class EditorPart extends Part implements IEditorGroupsService, IEditorGro } private updateContainer(): void { - toggleClass(this.container, 'empty', this.isEmpty); + const container = assertIsDefined(this.container); + toggleClass(container, 'empty', this.isEmpty); } private notifyGroupIndexChange(): void { diff --git a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts index 6db4dd3c4f8..848e0976bd8 100644 --- a/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts +++ b/src/vs/workbench/browser/parts/quickopen/quickOpenController.ts @@ -69,21 +69,21 @@ export class QuickOpenController extends Component implements IQuickOpenService private readonly _onHide: Emitter = this._register(new Emitter()); readonly onHide: Event = this._onHide.event; - private preserveInput: boolean; - private isQuickOpen: boolean; - private lastInputValue: string; - private lastSubmittedInputValue: string; - private quickOpenWidget: QuickOpenWidget; + private preserveInput: boolean | undefined; + private isQuickOpen: boolean | undefined; + private lastInputValue: string | undefined; + private lastSubmittedInputValue: string | undefined; + private quickOpenWidget: QuickOpenWidget | undefined; private mapResolvedHandlersToPrefix: Map> = new Map(); private mapContextKeyToContext: Map> = new Map(); private handlerOnOpenCalled: Set = new Set(); private promisesToCompleteOnHide: ValueCallback[] = []; - private previousActiveHandlerDescriptor: QuickOpenHandlerDescriptor | null; + private previousActiveHandlerDescriptor: QuickOpenHandlerDescriptor | null | undefined; private actionProvider = new ContributableActionProvider(); - private closeOnFocusLost: boolean; - private searchInEditorHistory: boolean; + private closeOnFocusLost: boolean | undefined; + private searchInEditorHistory: boolean | undefined; private editorHistoryHandler: EditorHistoryHandler; - private pendingGetResultsInvocation: CancellationTokenSource | null; + private pendingGetResultsInvocation: CancellationTokenSource | null = null; constructor( @IEditorGroupsService private readonly editorGroupService: IEditorGroupsService, @@ -173,12 +173,12 @@ export class QuickOpenController extends Component implements IQuickOpenService // Create upon first open if (!this.quickOpenWidget) { - this.quickOpenWidget = this._register(new QuickOpenWidget( + const quickOpenWidget: QuickOpenWidget = this.quickOpenWidget = this._register(new QuickOpenWidget( this.layoutService.getWorkbenchElement(), { onOk: () => this.onOk(), onCancel: () => { /* ignore */ }, - onType: (value: string) => this.onType(value || ''), + onType: (value: string) => this.onType(quickOpenWidget, value || ''), onShow: () => this.handleOnShow(), onHide: (reason) => this.handleOnHide(reason), onFocusLost: () => !this.closeOnFocusLost @@ -186,8 +186,7 @@ export class QuickOpenController extends Component implements IQuickOpenService 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 })); const quickOpenContainer = this.quickOpenWidget.create(); @@ -339,7 +338,7 @@ export class QuickOpenController extends Component implements IQuickOpenService } } - private onType(value: string): void { + private onType(quickOpenWidget: QuickOpenWidget, value: string): void { // cancel any pending get results invocation and create new this.cancelPendingGetResultsInvocation(); @@ -356,11 +355,11 @@ export class QuickOpenController extends Component implements IQuickOpenService // Reset Progress if (!instantProgress) { - this.quickOpenWidget.getProgressBar().stop().hide(); + quickOpenWidget.getProgressBar().stop().hide(); } // Reset Extra Class - this.quickOpenWidget.setExtraClass(null); + quickOpenWidget.setExtraClass(null); // Update context this.setQuickOpenContextKey(contextKey); @@ -374,7 +373,7 @@ export class QuickOpenController extends Component implements IQuickOpenService // Trigger onOpen this.resolveHandler(handlerDescriptor || defaultHandlerDescriptor); - this.quickOpenWidget.setInput(this.getEditorHistoryWithGroupLabel(), { autoFocusFirstEntry: true }); + quickOpenWidget.setInput(this.getEditorHistoryWithGroupLabel(), { autoFocusFirstEntry: true }); // If quickOpen entered empty we have to clear the prefill-cache this.lastInputValue = ''; @@ -388,7 +387,7 @@ export class QuickOpenController extends Component implements IQuickOpenService if (handlerDescriptor) { this.isQuickOpen = false; - resultPromise = this.handleSpecificHandler(handlerDescriptor, value, pendingResultsInvocationToken); + resultPromise = this.handleSpecificHandler(quickOpenWidget, handlerDescriptor, value, pendingResultsInvocationToken); } // Otherwise handle default handlers if no specific handler present @@ -396,7 +395,7 @@ export class QuickOpenController extends Component implements IQuickOpenService this.isQuickOpen = true; // Cache the value for prefilling the quickOpen next time is opened this.lastInputValue = trimmedValue; - resultPromise = this.handleDefaultHandler(defaultHandlerDescriptor, value, pendingResultsInvocationToken); + resultPromise = this.handleDefaultHandler(quickOpenWidget, defaultHandlerDescriptor, value, pendingResultsInvocationToken); } // Remember as the active one @@ -405,7 +404,7 @@ export class QuickOpenController extends Component implements IQuickOpenService // Progress if task takes a long time setTimeout(() => { if (!resultPromiseDone && !pendingResultsInvocationToken.isCancellationRequested) { - this.quickOpenWidget.getProgressBar().infinite().show(); + quickOpenWidget.getProgressBar().infinite().show(); } }, instantProgress ? 0 : 800); @@ -414,7 +413,7 @@ export class QuickOpenController extends Component implements IQuickOpenService resultPromiseDone = true; if (!pendingResultsInvocationToken.isCancellationRequested) { - this.quickOpenWidget.getProgressBar().hide(); + quickOpenWidget.getProgressBar().hide(); } pendingResultsInvocationTokenSource.dispose(); @@ -428,7 +427,7 @@ export class QuickOpenController extends Component implements IQuickOpenService }); } - private async handleDefaultHandler(handler: QuickOpenHandlerDescriptor, value: string, token: CancellationToken): Promise { + private async handleDefaultHandler(quickOpenWidget: QuickOpenWidget, handler: QuickOpenHandlerDescriptor, value: string, token: CancellationToken): Promise { // Fill in history results if matching and we are configured to search in history let matchingHistoryEntries: QuickOpenEntry[]; @@ -451,7 +450,7 @@ export class QuickOpenController extends Component implements IQuickOpenService // If we have matching entries from history we want to show them directly and not wait for the other results to come in // This also applies when we used to have entries from a previous run and now there are no more history results matching - const previousInput = this.quickOpenWidget.getInput(); + const previousInput = quickOpenWidget.getInput(); const wasShowingHistory = previousInput && previousInput.entries && previousInput.entries.some(e => e instanceof EditorHistoryEntry || e instanceof EditorHistoryEntryGroup); if (wasShowingHistory || matchingHistoryEntries.length > 0) { (async () => { @@ -460,7 +459,7 @@ export class QuickOpenController extends Component implements IQuickOpenService } if (!token.isCancellationRequested && !inputSet) { - this.quickOpenWidget.setInput(quickOpenModel, { autoFocusFirstEntry: true }); + quickOpenWidget.setInput(quickOpenModel, { autoFocusFirstEntry: true }); inputSet = true; } })(); @@ -472,17 +471,17 @@ export class QuickOpenController extends Component implements IQuickOpenService // now is the time to show the input if we did not have set it before if (!inputSet) { - this.quickOpenWidget.setInput(quickOpenModel, { autoFocusFirstEntry: true }); + quickOpenWidget.setInput(quickOpenModel, { autoFocusFirstEntry: true }); inputSet = true; } // merge history and default handler results const handlerResults = (result && result.entries) || []; - this.mergeResults(quickOpenModel, handlerResults, types.withNullAsUndefined(resolvedHandler.getGroupLabel())); + this.mergeResults(quickOpenWidget, quickOpenModel, handlerResults, types.withNullAsUndefined(resolvedHandler.getGroupLabel())); } } - private mergeResults(quickOpenModel: QuickOpenModel, handlerResults: QuickOpenEntry[], groupLabel: string | undefined): void { + private mergeResults(quickOpenWidget: QuickOpenWidget, quickOpenModel: QuickOpenModel, handlerResults: QuickOpenEntry[], groupLabel: string | undefined): void { // Remove results already showing by checking for a "resource" property const mapEntryToResource = this.mapEntriesToResource(quickOpenModel); @@ -501,17 +500,17 @@ export class QuickOpenController extends Component implements IQuickOpenService const useTopBorder = quickOpenModel.getEntries().length > 0; additionalHandlerResults[0] = new QuickOpenEntryGroup(additionalHandlerResults[0], groupLabel, useTopBorder); quickOpenModel.addEntries(additionalHandlerResults); - this.quickOpenWidget.refresh(quickOpenModel, { autoFocusFirstEntry }); + quickOpenWidget.refresh(quickOpenModel, { autoFocusFirstEntry }); } // Otherwise if no results are present (even from histoy) indicate this to the user else if (quickOpenModel.getEntries().length === 0) { quickOpenModel.addEntries([new PlaceholderQuickOpenEntry(nls.localize('noResultsFound1', "No results found"))]); - this.quickOpenWidget.refresh(quickOpenModel, { autoFocusFirstEntry: true }); + quickOpenWidget.refresh(quickOpenModel, { autoFocusFirstEntry: true }); } } - private async handleSpecificHandler(handlerDescriptor: QuickOpenHandlerDescriptor, value: string, token: CancellationToken): Promise { + private async handleSpecificHandler(quickOpenWidget: QuickOpenWidget, handlerDescriptor: QuickOpenHandlerDescriptor, value: string, token: CancellationToken): Promise { const resolvedHandler = await this.resolveHandler(handlerDescriptor); // Remove handler prefix from search value @@ -523,7 +522,7 @@ export class QuickOpenController extends Component implements IQuickOpenService const placeHolderLabel = (typeof canRun === 'string') ? canRun : nls.localize('canNotRunPlaceholder', "This quick open handler can not be used in the current context"); const model = new QuickOpenModel([new PlaceholderQuickOpenEntry(placeHolderLabel)], this.actionProvider); - this.showModel(model, resolvedHandler.getAutoFocus(value, { model, quickNavigateConfiguration: this.quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); + this.showModel(quickOpenWidget, model, resolvedHandler.getAutoFocus(value, { model, quickNavigateConfiguration: quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); return; } @@ -531,12 +530,12 @@ export class QuickOpenController extends Component implements IQuickOpenService // Support extra class from handler const extraClass = resolvedHandler.getClass(); if (extraClass) { - this.quickOpenWidget.setExtraClass(extraClass); + quickOpenWidget.setExtraClass(extraClass); } // When handlers change, clear the result list first before loading the new results if (this.previousActiveHandlerDescriptor !== handlerDescriptor) { - this.clearModel(); + this.clearModel(quickOpenWidget); } // Receive Results from Handler and apply @@ -544,28 +543,28 @@ export class QuickOpenController extends Component implements IQuickOpenService if (!token.isCancellationRequested) { if (!result || !result.entries.length) { const model = new QuickOpenModel([new PlaceholderQuickOpenEntry(resolvedHandler.getEmptyLabel(value))]); - this.showModel(model, resolvedHandler.getAutoFocus(value, { model, quickNavigateConfiguration: this.quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); + this.showModel(quickOpenWidget, model, resolvedHandler.getAutoFocus(value, { model, quickNavigateConfiguration: quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); } else { - this.showModel(result, resolvedHandler.getAutoFocus(value, { model: result, quickNavigateConfiguration: this.quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); + this.showModel(quickOpenWidget, result, resolvedHandler.getAutoFocus(value, { model: result, quickNavigateConfiguration: quickOpenWidget.getQuickNavigateConfiguration() }), types.withNullAsUndefined(resolvedHandler.getAriaLabel())); } } } - private showModel(model: IModel, autoFocus?: IAutoFocus, ariaLabel?: string): void { + private showModel(quickOpenWidget: QuickOpenWidget, model: IModel, autoFocus?: IAutoFocus, ariaLabel?: string): void { // If the given model is already set in the widget, refresh and return early - if (this.quickOpenWidget.getInput() === model) { - this.quickOpenWidget.refresh(model, autoFocus); + if (quickOpenWidget.getInput() === model) { + quickOpenWidget.refresh(model, autoFocus); return; } // Otherwise just set it - this.quickOpenWidget.setInput(model, autoFocus, ariaLabel); + quickOpenWidget.setInput(model, autoFocus, ariaLabel); } - private clearModel(): void { - this.showModel(new QuickOpenModel(), undefined); + private clearModel(quickOpenWidget: QuickOpenWidget): void { + this.showModel(quickOpenWidget, new QuickOpenModel(), undefined); } private mapEntriesToResource(model: QuickOpenModel): { [resource: string]: QuickOpenEntry; } { diff --git a/src/vs/workbench/browser/workbench.ts b/src/vs/workbench/browser/workbench.ts index cea697d588d..455bcacba91 100644 --- a/src/vs/workbench/browser/workbench.ts +++ b/src/vs/workbench/browser/workbench.ts @@ -157,7 +157,7 @@ export class Workbench extends Layout { this.renderWorkbench(instantiationService, accessor.get(INotificationService) as NotificationService, storageService, configurationService); // Workbench Layout - this.createWorkbenchLayout(instantiationService); + this.createWorkbenchLayout(); // Layout this.layout();