Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2

This commit is contained in:
ADS Merger
2020-04-23 02:50:35 +00:00
committed by Anthony Dresser
parent 3603f55d97
commit 7f1d8fc32f
659 changed files with 22709 additions and 12497 deletions

View File

@@ -27,7 +27,7 @@ import { URI } from 'vs/base/common/uri';
import { dirname, basename } from 'vs/base/common/resources';
import { LIGHT, FileThemeIcon, FolderThemeIcon, registerThemingParticipant, IThemeService } from 'vs/platform/theme/common/themeService';
import { FileKind } from 'vs/platform/files/common/files';
import { WorkbenchAsyncDataTree, ResourceNavigator } from 'vs/platform/list/browser/listService';
import { WorkbenchAsyncDataTree, TreeResourceNavigator } from 'vs/platform/list/browser/listService';
import { localize } from 'vs/nls';
import { timeout } from 'vs/base/common/async';
import { editorFindMatchHighlight, editorFindMatchHighlightBorder, textLinkForeground, textCodeBlockBackground, focusBorder } from 'vs/platform/theme/common/colorRegistry';
@@ -416,9 +416,9 @@ export class CustomTreeView extends Disposable implements ITreeView {
accessibilityProvider: {
getAriaLabel(element: ITreeItem): string {
return element.label ? element.label.label : '';
}
},
getWidgetAriaLabel: () => this.title
},
ariaLabel: this.title,
keyboardNavigationLabelProvider: {
getKeyboardNavigationLabel: (item: ITreeItem) => {
return item.label ? item.label.label : (item.resourceUri ? basename(URI.revive(item.resourceUri)) : undefined);
@@ -451,7 +451,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
}));
this.tree.setInput(this.root).then(() => this.updateContentAreas());
const customTreeNavigator = ResourceNavigator.createTreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false });
const customTreeNavigator = new TreeResourceNavigator(this.tree, { openOnFocus: false, openOnSelection: false });
this._register(customTreeNavigator);
this._register(customTreeNavigator.onDidOpenResource(e => {
if (!e.browserEvent) {

View File

@@ -28,7 +28,8 @@ class AccountsStatusBarContributions extends Disposable implements IWorkbenchCon
this._register(
this.statusbarService.addEntry({
command: 'workbench.actions.modal.linkedAccount',
text: '$(person-filled)'
text: '$(person-filled)',
ariaLabel: 'Accounts'
},
'status.accountList',
localize('status.problems', "Problems"),

View File

@@ -30,6 +30,7 @@ export class ConnectionStatusbarItem extends Disposable implements IWorkbenchCon
this.statusItem = this._register(
this.statusbarService.addEntry({
text: '',
ariaLabel: ''
},
ConnectionStatusbarItem.ID,
localize('status.connection.status', "Connection Status"),
@@ -84,7 +85,7 @@ export class ConnectionStatusbarItem extends Disposable implements IWorkbenchCon
}
this.statusItem.update({
text, tooltip
text, ariaLabel: text, tooltip
});
}
}

View File

@@ -105,7 +105,7 @@ export class DataExplorerViewPaneContainer extends ViewPaneContainer {
@IContextKeyService private contextKeyService: IContextKeyService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
) {
super(VIEWLET_ID, `${VIEWLET_ID}.state`, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
super(VIEWLET_ID, { mergeViewWithContainerWhenSingleView: true }, instantiationService, configurationService, layoutService, contextMenuService, telemetryService, extensionService, themeService, storageService, contextService, viewDescriptorService);
}
create(parent: HTMLElement): void {

View File

@@ -88,11 +88,13 @@ export class EditDataEditor extends BaseEditor {
}
if (_editorService) {
_editorService.overrideOpenEditor((editor, options, group) => {
if (this.isVisible() && (editor !== this.input || group !== this.group)) {
this.saveEditorViewState();
_editorService.overrideOpenEditor({
open: (editor, options, group) => {
if (this.isVisible() && (editor !== this.input || group !== this.group)) {
this.saveEditorViewState();
}
return {};
}
return {};
});
}
}

View File

@@ -27,7 +27,9 @@ export class EditorReplacementContribution implements IWorkbenchContribution {
@IEditorService private readonly editorService: IEditorService,
@IModeService private readonly modeService: IModeService
) {
this.editorOpeningListener = this.editorService.overrideOpenEditor((editor, options, group) => this.onEditorOpening(editor, options, group));
this.editorOpeningListener = this.editorService.overrideOpenEditor({
open: (editor, options, group) => this.onEditorOpening(editor, options, group)
});
}
private onEditorOpening(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup): IOpenEditorOverride | undefined {

View File

@@ -194,7 +194,7 @@ class MockEditorService extends TestEditorService {
fireOpenEditor(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup) {
for (const handler of this.overridenOpens) {
let response: IOpenEditorOverride | undefined;
if (response = handler(editor, options, group)) {
if (response = handler.open(editor, options, group)) {
return response;
}
}

View File

@@ -0,0 +1,140 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { IProductService } from 'vs/platform/product/common/productService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { localize } from 'vs/nls';
import { IExtensionRecommendation } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
import { visualizerExtensions } from 'sql/workbench/contrib/extensions/common/constants';
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { InstallRecommendedExtensionsByScenarioAction, ShowRecommendedExtensionsByScenarioAction } from 'sql/workbench/contrib/extensions/browser/extensionsActions';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
const choiceNever = localize('neverShowAgain', "Don't Show Again");
export class ScenarioRecommendations extends ExtensionRecommendations {
readonly _recommendations: ExtensionRecommendation[] = [];
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean,
@IProductService private readonly productService: IProductService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@INotificationService notificationService: INotificationService,
@ITelemetryService telemetryService: ITelemetryService,
@IStorageService storageService: IStorageService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
@IAdsTelemetryService private readonly adsTelemetryService: IAdsTelemetryService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
) {
super(isExtensionAllowedToBeRecommended, instantiationService, configurationService, notificationService, telemetryService, storageService, storageKeysSyncRegistryService);
// this._recommendations = productService.recommendedExtensionsByScenario.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' }));
}
protected async doActivate(): Promise<void> {
return;
}
// {{SQL CARBON EDIT}}
promptRecommendedExtensionsByScenario(scenarioType: string): void {
const storageKey = 'extensionAssistant/RecommendationsIgnore/' + scenarioType;
if (this.storageService.getBoolean(storageKey, StorageScope.GLOBAL, false)) {
return;
}
const visualizerExtensionNotificationService = 'VisualizerExtensionNotificationService';
let recommendationMessage = localize('ExtensionsRecommended', "Azure Data Studio has extension recommendations.");
if (scenarioType === visualizerExtensions) {
recommendationMessage = localize('VisualizerExtensionsRecommended', "Azure Data Studio has extension recommendations for data visualization.\nOnce installed, you can select the Visualizer icon to visualize your query results.");
}
Promise.all([this.getRecommendedExtensionsByScenario(scenarioType), this.extensionManagementService.getInstalled(ExtensionType.User)]).then(([recommendations, localExtensions]) => {
if (!recommendations.every(rec => { return localExtensions.findIndex(local => local.identifier.id.toLocaleLowerCase() === rec.extensionId.toLocaleLowerCase()) !== -1; })) {
return new Promise<void>(c => {
this.notificationService.prompt(
Severity.Info,
recommendationMessage,
[{
label: localize('installAll', "Install All"),
run: () => {
this.adsTelemetryService.sendActionEvent(
TelemetryKeys.TelemetryView.ExtensionRecommendationDialog,
TelemetryKeys.TelemetryAction.Click,
'InstallButton',
visualizerExtensionNotificationService
);
const installAllAction = this.instantiationService.createInstance(InstallRecommendedExtensionsByScenarioAction, scenarioType, recommendations);
installAllAction.run();
installAllAction.dispose();
}
}, {
label: localize('showRecommendations', "Show Recommendations"),
run: () => {
this.adsTelemetryService.sendActionEvent(
TelemetryKeys.TelemetryView.ExtensionRecommendationDialog,
TelemetryKeys.TelemetryAction.Click,
'ShowRecommendationsButton',
visualizerExtensionNotificationService
);
const showAction = this.instantiationService.createInstance(ShowRecommendedExtensionsByScenarioAction, scenarioType);
showAction.run();
showAction.dispose();
c(undefined);
}
}, {
label: choiceNever,
isSecondary: true,
run: () => {
this.adsTelemetryService.sendActionEvent(
TelemetryKeys.TelemetryView.ExtensionRecommendationDialog,
TelemetryKeys.TelemetryAction.Click,
'NeverShowAgainButton',
visualizerExtensionNotificationService
);
this.storageService.store(storageKey, true, StorageScope.GLOBAL);
c(undefined);
}
}],
{
sticky: true,
onCancel: () => {
this.adsTelemetryService.sendActionEvent(
TelemetryKeys.TelemetryView.ExtensionRecommendationDialog,
TelemetryKeys.TelemetryAction.Click,
'CancelButton',
visualizerExtensionNotificationService
);
c(undefined);
}
}
);
});
} else {
return Promise.resolve();
}
});
}
getRecommendedExtensionsByScenario(scenarioType: string): Promise<IExtensionRecommendation[]> {
if (!scenarioType) {
return Promise.reject(new Error(localize('scenarioTypeUndefined', 'The scenario type for extension recommendations must be provided.')));
}
return Promise.resolve((this.productService.recommendedExtensionsByScenario[scenarioType] || [])
.filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId))
.map(extensionId => (<IExtensionRecommendation>{ extensionId, sources: ['application'] })));
}
}

View File

@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { IProductService } from 'vs/platform/product/common/productService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { localize } from 'vs/nls';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
export class StaticRecommendations extends ExtensionRecommendations {
readonly _recommendations: ExtensionRecommendation[] = [];
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean,
@IProductService productService: IProductService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@INotificationService notificationService: INotificationService,
@ITelemetryService telemetryService: ITelemetryService,
@IStorageService storageService: IStorageService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
) {
super(isExtensionAllowedToBeRecommended, instantiationService, configurationService, notificationService, telemetryService, storageService, storageKeysSyncRegistryService);
this._recommendations = productService.recommendedExtensions.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' }));
}
protected async doActivate(): Promise<void> {
return;
}
}

View File

@@ -365,7 +365,8 @@ export class NotebookEditor extends BaseEditor implements IFindNotebookControlle
searchScope: true,
matchesPosition: false,
matchesCount: false,
currentMatch: false
currentMatch: false,
loop: true
};
this._notebookModel.cells.forEach(cell => {
this._register(cell.onCellModeChanged((state) => {
@@ -450,7 +451,8 @@ export class NotebookEditor extends BaseEditor implements IFindNotebookControlle
searchScope: false,
matchesPosition: false,
matchesCount: false,
currentMatch: false
currentMatch: false,
loop: true
};
this._onFindStateChange(changeEvent).catch(e => { onUnexpectedError(e); });
}

View File

@@ -172,11 +172,13 @@ export class ProfilerEditor extends BaseEditor {
this._profilerEditorContextKey = CONTEXT_PROFILER_EDITOR.bindTo(this._contextKeyService);
if (editorService) {
editorService.overrideOpenEditor((editor, options, group) => {
if (this.isVisible() && (editor !== this.input || group !== this.group)) {
this.saveEditorViewState();
editorService.overrideOpenEditor({
open: (editor, options, group) => {
if (this.isVisible() && (editor !== this.input || group !== this.group)) {
this.saveEditorViewState();
}
return {};
}
return {};
});
}
}
@@ -502,7 +504,8 @@ export class ProfilerEditor extends BaseEditor {
seedSearchStringFromSelection: (controller.getState().searchString.length === 0),
shouldFocus: FindStartFocusAction.FocusFindInput,
shouldAnimate: true,
updateSearchScope: false
updateSearchScope: false,
loop: true
});
}
} else {

View File

@@ -288,7 +288,7 @@ export class ProfilerTableEditor extends BaseEditor implements IProfilerControll
: localize('ProfilerTableEditor.eventCount', "Events: {0}", this._input.data.getLength());
this._disposeStatusbarItem();
this._statusbarItem = this._statusbarService.addEntry({ text: message }, 'status.eventCount', localize('status.eventCount', "Event Count"), StatusbarAlignment.RIGHT);
this._statusbarItem = this._statusbarService.addEntry({ text: message, ariaLabel: message }, 'status.eventCount', localize('status.eventCount', "Event Count"), StatusbarAlignment.RIGHT);
}
}

View File

@@ -74,8 +74,8 @@ export class SqlFlavorStatusbarItem extends Disposable implements IWorkbenchCont
this.statusItem = this._register(
this.statusbarService.addEntry({
text: nls.localize('changeProvider', "Change SQL language provider"),
ariaLabel: nls.localize('changeProvider', "Change SQL language provider"),
command: 'sql.action.editor.changeProvider'
},
SqlFlavorStatusbarItem.ID,
nls.localize('status.query.flavor', "SQL Language Flavor"),
@@ -161,6 +161,7 @@ export class SqlFlavorStatusbarItem extends Disposable implements IWorkbenchCont
private updateFlavorElement(text: string): void {
const props: IStatusbarEntry = {
text,
ariaLabel: text,
command: 'sql.action.editor.changeProvider'
};

View File

@@ -33,6 +33,7 @@ export class TimeElapsedStatusBarContributions extends Disposable implements IWo
this.statusItem = this._register(
this.statusbarService.addEntry({
text: '',
ariaLabel: ''
},
TimeElapsedStatusBarContributions.ID,
localize('status.query.timeElapsed', "Time Elapsed"),
@@ -89,20 +90,26 @@ export class TimeElapsedStatusBarContributions extends Disposable implements IWo
if (runner.isExecuting) {
this.intervalTimer.cancelAndSet(() => {
const value = runner.queryStartTime ? Date.now() - runner.queryStartTime.getTime() : 0;
const timeString = parseNumAsTimeString(value, false);
this.statusItem.update({
text: parseNumAsTimeString(value, false)
text: timeString,
ariaLabel: timeString
});
}, 1000);
const value = runner.queryStartTime ? Date.now() - runner.queryStartTime.getTime() : 0;
const timeString = parseNumAsTimeString(value, false);
this.statusItem.update({
text: parseNumAsTimeString(value, false)
text: timeString,
ariaLabel: timeString
});
} else {
const value = runner.queryStartTime && runner.queryEndTime
? runner.queryEndTime.getTime() - runner.queryStartTime.getTime() : 0;
const timeString = parseNumAsTimeString(value, false);
this.statusItem.update({
text: parseNumAsTimeString(value, false)
text: timeString,
ariaLabel: timeString
});
}
this.show();
@@ -126,6 +133,7 @@ export class RowCountStatusBarContributions extends Disposable implements IWorkb
this.statusItem = this._register(
this.statusbarService.addEntry({
text: '',
ariaLabel: ''
},
RowCountStatusBarContributions.ID,
localize('status.query.rowCount', "Row Count"),
@@ -191,7 +199,7 @@ export class RowCountStatusBarContributions extends Disposable implements IWorkb
}, 0);
}, 0);
const text = localize('rowCount', "{0} rows", rowCount.toLocaleString());
this.statusItem.update({ text });
this.statusItem.update({ text, ariaLabel: text });
this.show();
}
}
@@ -211,6 +219,7 @@ export class QueryStatusStatusBarContributions extends Disposable implements IWo
this._register(
this.statusbarService.addEntry({
text: localize('query.status.executing', "Executing query..."),
ariaLabel: localize('query.status.executing', "Executing query...")
},
QueryStatusStatusBarContributions.ID,
localize('status.query.status', "Execution Status"),