mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-31 01:00:29 -04:00
Merge from vscode e1d3dd53d17fb1529a002e4d6fb066db0a0bd385 (#6460)
* Merge from vscode e1d3dd53d17fb1529a002e4d6fb066db0a0bd385 * fix servers icon * fix tests
This commit is contained in:
@@ -18,6 +18,7 @@ import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { DefaultSettingsEditorContribution } from 'vs/workbench/contrib/preferences/browser/preferencesEditor';
|
||||
|
||||
const transientWordWrapState = 'transientWordWrapState';
|
||||
const isWordWrapMinifiedKey = 'isWordWrapMinified';
|
||||
@@ -131,6 +132,10 @@ class ToggleWordWrapAction extends EditorAction {
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
if (editor.getContribution(DefaultSettingsEditorContribution.ID)) {
|
||||
// in the settings editor...
|
||||
return;
|
||||
}
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
@@ -201,6 +206,10 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution
|
||||
}));
|
||||
|
||||
const ensureWordWrapSettings = () => {
|
||||
if (this.editor.getContribution(DefaultSettingsEditorContribution.ID)) {
|
||||
// in the settings editor...
|
||||
return;
|
||||
}
|
||||
// Ensure correct word wrap settings
|
||||
const newModel = this.editor.getModel();
|
||||
if (!newModel) {
|
||||
@@ -267,7 +276,7 @@ function canToggleWordWrap(uri: URI): boolean {
|
||||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
return (uri.scheme !== 'output' && uri.scheme !== 'vscode');
|
||||
return (uri.scheme !== 'output');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -311,7 +311,6 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
|
||||
let currentComment = commentThread.comments![i];
|
||||
let oldCommentNode = this._commentElements.filter(commentNode => commentNode.comment.uniqueIdInThread === currentComment.uniqueIdInThread);
|
||||
if (oldCommentNode.length) {
|
||||
oldCommentNode[0].update(currentComment);
|
||||
lastCommentElement = oldCommentNode[0].domNode;
|
||||
newCommentNodeList.unshift(oldCommentNode[0]);
|
||||
} else {
|
||||
|
||||
@@ -399,7 +399,8 @@
|
||||
}
|
||||
|
||||
.monaco-editor .review-widget .action-item {
|
||||
min-width: 16px;
|
||||
min-width: 18px;
|
||||
min-height: 18px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension
|
||||
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { EditorOptions } from 'vs/workbench/common/editor';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, DisabledLabelAction, SystemDisabledWarningAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { CombinedInstallAction, UpdateAction, ExtensionEditorDropDownAction, ReloadAction, MaliciousStatusLabelAction, IgnoreExtensionRecommendationAction, UndoIgnoreExtensionRecommendationAction, EnableDropDownAction, DisableDropDownAction, StatusLabelAction, SetFileIconThemeAction, SetColorThemeAction, RemoteInstallAction, ExtensionToolTipAction, SystemDisabledWarningAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
@@ -391,7 +391,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
this.instantiationService.createInstance(LocalInstallAction),
|
||||
combinedInstallAction,
|
||||
systemDisabledWarningAction,
|
||||
this.instantiationService.createInstance(DisabledLabelAction, systemDisabledWarningAction),
|
||||
this.instantiationService.createInstance(ExtensionToolTipAction, systemDisabledWarningAction, reloadAction),
|
||||
this.instantiationService.createInstance(MaliciousStatusLabelAction, true),
|
||||
];
|
||||
const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets]);
|
||||
|
||||
@@ -64,14 +64,15 @@ Registry.as<IQuickOpenRegistry>(Extensions.Quickopen).registerQuickOpenHandler(
|
||||
);
|
||||
|
||||
// Editor
|
||||
const editorDescriptor = new EditorDescriptor(
|
||||
ExtensionEditor,
|
||||
ExtensionEditor.ID,
|
||||
localize('extension', "Extension")
|
||||
);
|
||||
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors)
|
||||
.registerEditor(editorDescriptor, [new SyncDescriptor(ExtensionsInput)]);
|
||||
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
|
||||
new EditorDescriptor(
|
||||
ExtensionEditor,
|
||||
ExtensionEditor.ID,
|
||||
localize('extension', "Extension")
|
||||
),
|
||||
[
|
||||
new SyncDescriptor(ExtensionsInput)
|
||||
]);
|
||||
|
||||
// Viewlet
|
||||
const viewletDescriptor = new ViewletDescriptor(
|
||||
|
||||
@@ -61,11 +61,11 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; // {{SQL CARBON EDIT}}
|
||||
|
||||
function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
|
||||
export function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
|
||||
return {
|
||||
identifier: new ExtensionIdentifier(local.identifier.id),
|
||||
isBuiltin: local.type === ExtensionType.System,
|
||||
@@ -76,7 +76,8 @@ function toExtensionDescription(local: ILocalExtension): IExtensionDescription {
|
||||
};
|
||||
}
|
||||
|
||||
const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error, instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => {
|
||||
const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error,
|
||||
instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => {
|
||||
if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.extensionsGallery) {
|
||||
return Promise.reject(error);
|
||||
} else {
|
||||
@@ -1182,9 +1183,7 @@ export class ReloadAction extends ExtensionAction {
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
) {
|
||||
super('extensions.reload', localize('reloadAction', "Reload"), ReloadAction.DisabledClass, false);
|
||||
this._register(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this));
|
||||
@@ -1232,8 +1231,9 @@ export class ReloadAction extends ExtensionAction {
|
||||
}
|
||||
if (this.extension.local) {
|
||||
const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local);
|
||||
|
||||
// Extension is runningÎ
|
||||
if (runningExtension) {
|
||||
// Extension is running
|
||||
if (isEnabled) {
|
||||
if (!this.extensionService.canAddExtension(toExtensionDescription(this.extension.local))) {
|
||||
if (isSameExtensionRunning) {
|
||||
@@ -1259,39 +1259,27 @@ export class ReloadAction extends ExtensionAction {
|
||||
}
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Extension is not running
|
||||
}
|
||||
|
||||
// Extension is not running
|
||||
else {
|
||||
if (isEnabled && !this.extensionService.canAddExtension(toExtensionDescription(this.extension.local))) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension."); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const uiExtension = isUIExtension(this.extension.local.manifest, this.productService, this.configurationService);
|
||||
// Local Workspace Extension
|
||||
if (!uiExtension && this.extension.server === this.extensionManagementServerService.localExtensionManagementServer) {
|
||||
const remoteExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.remoteExtensionManagementServer)[0];
|
||||
// Extension exist in remote and enabled
|
||||
if (remoteExtension && remoteExtension.local && this.extensionEnablementService.isEnabled(remoteExtension.local)) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension.");// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName)); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Remote UI Extension
|
||||
if (uiExtension && this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
const localExtension = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === this.extensionManagementServerService.localExtensionManagementServer)[0];
|
||||
// Extension exist in local and enabled
|
||||
if (localExtension && localExtension.local && this.extensionEnablementService.isEnabled(localExtension.local)) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension."); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName)); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
|
||||
const otherServer = this.extension.server ? this.extension.server === this.extensionManagementServerService.localExtensionManagementServer ? this.extensionManagementServerService.remoteExtensionManagementServer : this.extensionManagementServerService.localExtensionManagementServer : null;
|
||||
if (otherServer && this.extension.enablementState === EnablementState.DisabledByExtensionKind) {
|
||||
const extensionInOtherServer = this.extensionsWorkbenchService.local.filter(e => areSameExtensions(e.identifier, this.extension.identifier) && e.server === otherServer)[0];
|
||||
// Same extension in other server exists and
|
||||
if (extensionInOtherServer && extensionInOtherServer.local && this.extensionEnablementService.isEnabled(extensionInOtherServer.local)) {
|
||||
this.enabled = true;
|
||||
this.label = localize('reloadRequired', "Reload Required");
|
||||
this.tooltip = localize('postEnableTooltip', "Please reload Azure Data Studio to enable this extension."); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
alert(localize('installExtensionComplete', "Installing extension {0} is completed. Please reload Azure Data Studio to enable it.", this.extension.displayName)); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2548,7 +2536,7 @@ export class MaliciousStatusLabelAction extends ExtensionAction {
|
||||
}
|
||||
}
|
||||
|
||||
export class DisabledLabelAction extends ExtensionAction {
|
||||
export class ExtensionToolTipAction extends ExtensionAction {
|
||||
|
||||
private static readonly Class = 'disable-status';
|
||||
|
||||
@@ -2557,10 +2545,12 @@ export class DisabledLabelAction extends ExtensionAction {
|
||||
|
||||
constructor(
|
||||
private readonly warningAction: SystemDisabledWarningAction,
|
||||
private readonly reloadAction: ReloadAction,
|
||||
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService
|
||||
) {
|
||||
super('extensions.disabledLabel', warningAction.tooltip, `${DisabledLabelAction.Class} hide`, false);
|
||||
super('extensions.tooltip', warningAction.tooltip, `${ExtensionToolTipAction.Class} hide`, false);
|
||||
this._register(warningAction.onDidChange(() => this.update(), this));
|
||||
this._register(this.extensionService.onDidChangeExtensions(this.updateRunningExtensions, this));
|
||||
this.updateRunningExtensions();
|
||||
@@ -2571,25 +2561,51 @@ export class DisabledLabelAction extends ExtensionAction {
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.class = `${DisabledLabelAction.Class} hide`;
|
||||
this.label = '';
|
||||
this.label = this.getTooltip();
|
||||
this.class = ExtensionToolTipAction.Class;
|
||||
if (!this.label) {
|
||||
this.class = `${ExtensionToolTipAction.Class} hide`;
|
||||
}
|
||||
}
|
||||
|
||||
private getTooltip(): string {
|
||||
if (!this.extension) {
|
||||
return '';
|
||||
}
|
||||
if (this.reloadAction.enabled) {
|
||||
return this.reloadAction.tooltip;
|
||||
}
|
||||
if (this.warningAction.tooltip) {
|
||||
this.class = DisabledLabelAction.Class;
|
||||
this.label = this.warningAction.tooltip;
|
||||
return;
|
||||
return this.warningAction.tooltip;
|
||||
}
|
||||
if (this.extension && this.extension.local && isLanguagePackExtension(this.extension.local.manifest)) {
|
||||
return;
|
||||
}
|
||||
if (this.extension && this.extension.local && this._runningExtensions) {
|
||||
if (this.extension && this.extension.local && this.extension.state === ExtensionState.Installed && this._runningExtensions) {
|
||||
const isRunning = this._runningExtensions.some(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension.identifier));
|
||||
const isEnabled = this.extensionEnablementService.isEnabled(this.extension.local);
|
||||
const isExtensionRunning = this._runningExtensions.some(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, this.extension.identifier));
|
||||
if (!isExtensionRunning && !isEnabled && this.extensionEnablementService.canChangeEnablement(this.extension.local)) {
|
||||
this.class = DisabledLabelAction.Class;
|
||||
this.label = localize('disabled by user', "This extension is disabled by the user.");
|
||||
return;
|
||||
|
||||
if (isEnabled && isRunning) {
|
||||
if (this.extensionManagementServerService.localExtensionManagementServer && this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return localize('extension enabled on remote', "Extension is enabled on '{0}'", this.extension.server.label);
|
||||
}
|
||||
}
|
||||
if (this.extension.enablementState === EnablementState.EnabledGlobally) {
|
||||
return localize('globally enabled', "This extension is enabled globally.");
|
||||
}
|
||||
if (this.extension.enablementState === EnablementState.EnabledWorkspace) {
|
||||
return localize('workspace enabled', "This extension is enabled for this workspace by the user.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEnabled && !isRunning) {
|
||||
if (this.extension.enablementState === EnablementState.DisabledGlobally) {
|
||||
return localize('globally disabled', "This extension is disabled globally by the user.");
|
||||
}
|
||||
if (this.extension.enablementState === EnablementState.DisabledWorkspace) {
|
||||
return localize('workspace disabled', "This extension is disabled for this workspace by the user.");
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
run(): Promise<any> {
|
||||
@@ -2832,6 +2848,7 @@ export class InstallVSIXAction extends Action {
|
||||
@IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IWindowService private readonly windowService: IWindowService,
|
||||
@IFileDialogService private readonly fileDialogService: IFileDialogService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
// {{SQL CARBON EDIT}}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, DisabledLabelAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { InstallAction, UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, ExtensionActionViewItem, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteBadgeWidget, TooltipWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
@@ -103,8 +103,8 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
systemDisabledWarningAction,
|
||||
this.instantiationService.createInstance(ManageExtensionAction)
|
||||
];
|
||||
const disabledLabelAction = this.instantiationService.createInstance(DisabledLabelAction, systemDisabledWarningAction);
|
||||
const tooltipWidget = this.instantiationService.createInstance(TooltipWidget, root, disabledLabelAction, recommendationWidget, reloadAction);
|
||||
const extensionTooltipAction = this.instantiationService.createInstance(ExtensionToolTipAction, systemDisabledWarningAction, reloadAction);
|
||||
const tooltipWidget = this.instantiationService.createInstance(TooltipWidget, root, extensionTooltipAction, recommendationWidget);
|
||||
const widgets = [
|
||||
recommendationWidget,
|
||||
iconRemoteBadgeWidget,
|
||||
@@ -115,10 +115,10 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
// this.instantiationService.createInstance(InstallCountWidget, installCount, true),
|
||||
this.instantiationService.createInstance(RatingsWidget, ratings, true)
|
||||
];
|
||||
const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets, disabledLabelAction]);
|
||||
const extensionContainers: ExtensionContainers = this.instantiationService.createInstance(ExtensionContainers, [...actions, ...widgets, extensionTooltipAction]);
|
||||
|
||||
actionbar.push(actions, actionOptions);
|
||||
const disposables = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers, disabledLabelAction);
|
||||
const disposables = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers, extensionTooltipAction);
|
||||
|
||||
return {
|
||||
// {{SQL CARBON EDIT}}
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
import 'vs/css!./media/extensionsWidgets';
|
||||
import { Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer, ExtensionState } from '../common/extensions';
|
||||
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { append, $, addClass } from 'vs/base/browser/dom';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IExtensionTipsService, IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { extensionButtonProminentBackground, extensionButtonProminentForeground, DisabledLabelAction, ReloadAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { extensionButtonProminentBackground, extensionButtonProminentForeground, ExtensionToolTipAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
|
||||
import { EXTENSION_BADGE_REMOTE_BACKGROUND, EXTENSION_BADGE_REMOTE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
@@ -145,16 +145,13 @@ export class TooltipWidget extends ExtensionWidget {
|
||||
|
||||
constructor(
|
||||
private readonly parent: HTMLElement,
|
||||
private readonly disabledLabelAction: DisabledLabelAction,
|
||||
private readonly tooltipAction: ExtensionToolTipAction,
|
||||
private readonly recommendationWidget: RecommendationWidget,
|
||||
private readonly reloadAction: ReloadAction,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@ILabelService private readonly labelService: ILabelService
|
||||
) {
|
||||
super();
|
||||
this._register(Event.any<any>(
|
||||
this.disabledLabelAction.onDidChange,
|
||||
this.reloadAction.onDidChange,
|
||||
this.tooltipAction.onDidChange,
|
||||
this.recommendationWidget.onDidChangeTooltip,
|
||||
this.labelService.onDidChangeFormatters
|
||||
)(() => this.render()));
|
||||
@@ -173,17 +170,8 @@ export class TooltipWidget extends ExtensionWidget {
|
||||
if (!this.extension) {
|
||||
return '';
|
||||
}
|
||||
if (this.reloadAction.enabled) {
|
||||
return this.reloadAction.tooltip;
|
||||
}
|
||||
if (this.disabledLabelAction.label) {
|
||||
return this.disabledLabelAction.label;
|
||||
}
|
||||
if (this.extension.local && this.extension.state === ExtensionState.Installed) {
|
||||
if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
||||
return localize('extension enabled on remote', "Extension is enabled on '{0}'", this.extension.server.label);
|
||||
}
|
||||
return localize('extension enabled locally', "Extension is enabled locally.");
|
||||
if (this.tooltipAction.tooltip) {
|
||||
return this.tooltipAction.tooltip;
|
||||
}
|
||||
return this.recommendationWidget.tooltip;
|
||||
}
|
||||
|
||||
@@ -424,7 +424,9 @@ class Extensions extends Disposable {
|
||||
const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0] : null;
|
||||
this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing;
|
||||
|
||||
let extension: Extension | undefined = installingExtension ? installingExtension : zipPath ? this.instantiationService.createInstance(Extension, this.stateProvider, this.server, local, undefined) : undefined;
|
||||
let extension: Extension | undefined = installingExtension ? installingExtension
|
||||
: (zipPath || local) ? this.instantiationService.createInstance(Extension, this.stateProvider, this.server, local, undefined)
|
||||
: undefined;
|
||||
if (extension) {
|
||||
if (local) {
|
||||
const installed = this.installed.filter(e => areSameExtensions(e.identifier, extension!.identifier))[0];
|
||||
|
||||
@@ -1063,37 +1063,39 @@ suite('ExtensionsActions Test', () => {
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension state is installing', () => {
|
||||
test('Test ReloadAction when extension state is installing', async () => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
const gallery = aGalleryExtension('a');
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
return workbenchService.queryGallery(CancellationToken.None)
|
||||
.then((paged) => {
|
||||
testObject.extension = paged.firstPage[0];
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
const paged = await workbenchService.queryGallery(CancellationToken.None);
|
||||
testObject.extension = paged.firstPage[0];
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension state is uninstalling', () => {
|
||||
test('Test ReloadAction when extension state is uninstalling', async () => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const local = aLocalExtension('a');
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
|
||||
return instantiationService.get(IExtensionsWorkbenchService).queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
uninstallEvent.fire(local.identifier);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
uninstallEvent.fire(local.identifier);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is newly installed', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
const runningExtensions = [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }];
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve(runningExtensions),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const gallery = aGalleryExtension('a');
|
||||
@@ -1103,35 +1105,50 @@ suite('ExtensionsActions Test', () => {
|
||||
testObject.extension = paged.firstPage[0];
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
return new Promise(c => {
|
||||
testObject.onDidChange(() => {
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
if (testObject.enabled && testObject.tooltip === 'Please reload Azure Data Studio to enable this extension.') {
|
||||
c();
|
||||
}
|
||||
});
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, gallery) });
|
||||
});
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, gallery) });
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal(testObject.tooltip, 'Please reload Azure Data Studio to enable this extension.'); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is installed and uninstalled', () => {
|
||||
test('Test ReloadAction when extension is newly installed and reload is not required', async () => {
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
const runningExtensions = [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }];
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve(runningExtensions),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => true
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const gallery = aGalleryExtension('a');
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
const paged = await instantiationService.get(IExtensionsWorkbenchService).queryGallery(CancellationToken.None);
|
||||
testObject.extension = paged.firstPage[0];
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, gallery) });
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is installed and uninstalled', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const gallery = aGalleryExtension('a');
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
return instantiationService.get(IExtensionsWorkbenchService).queryGallery(CancellationToken.None)
|
||||
.then((paged) => {
|
||||
testObject.extension = paged.firstPage[0];
|
||||
const identifier = gallery.identifier;
|
||||
installEvent.fire({ identifier, gallery });
|
||||
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, { identifier }) });
|
||||
uninstallEvent.fire(identifier);
|
||||
didUninstallEvent.fire({ identifier });
|
||||
const paged = await instantiationService.get(IExtensionsWorkbenchService).queryGallery(CancellationToken.None);
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
testObject.extension = paged.firstPage[0];
|
||||
const identifier = gallery.identifier;
|
||||
installEvent.fire({ identifier, gallery });
|
||||
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, { identifier }) });
|
||||
uninstallEvent.fire(identifier);
|
||||
didUninstallEvent.fire({ identifier });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is uninstalled', async () => {
|
||||
@@ -1145,8 +1162,7 @@ suite('ExtensionsActions Test', () => {
|
||||
|
||||
return new Promise(c => {
|
||||
testObject.onDidChange(() => {
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
if (testObject.enabled && testObject.tooltip === 'Please reload Azure Data Studio to complete the uninstallation of this extension.') {
|
||||
if (testObject.enabled && testObject.tooltip === 'Please reload Azure Data Studio to complete the uninstallation of this extension.') { // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
c();
|
||||
}
|
||||
});
|
||||
@@ -1155,25 +1171,24 @@ suite('ExtensionsActions Test', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is uninstalled and installed', () => {
|
||||
test('Test ReloadAction when extension is uninstalled and installed', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.0', extensionLocation: URI.file('pub.a') }]);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const local = aLocalExtension('a');
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return instantiationService.get(IExtensionsWorkbenchService).queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
uninstallEvent.fire(local.identifier);
|
||||
didUninstallEvent.fire({ identifier: local.identifier });
|
||||
const extensions = await instantiationService.get(IExtensionsWorkbenchService).queryLocal();
|
||||
|
||||
const gallery = aGalleryExtension('a');
|
||||
const identifier = gallery.identifier;
|
||||
installEvent.fire({ identifier, gallery });
|
||||
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local });
|
||||
testObject.extension = extensions[0];
|
||||
uninstallEvent.fire(local.identifier);
|
||||
didUninstallEvent.fire({ identifier: local.identifier });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
const gallery = aGalleryExtension('a');
|
||||
const identifier = gallery.identifier;
|
||||
installEvent.fire({ identifier, gallery });
|
||||
didInstallEvent.fire({ identifier, gallery, operation: InstallOperation.Install, local });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is updated while running', async () => {
|
||||
@@ -1188,8 +1203,7 @@ suite('ExtensionsActions Test', () => {
|
||||
|
||||
return new Promise(c => {
|
||||
testObject.onDidChange(() => {
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
if (testObject.enabled && testObject.tooltip === 'Please reload Azure Data Studio to enable the updated extension.') {
|
||||
if (testObject.enabled && testObject.tooltip === 'Please reload Azure Data Studio to enable the updated extension.') { // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
c();
|
||||
}
|
||||
});
|
||||
@@ -1199,131 +1213,103 @@ suite('ExtensionsActions Test', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is updated when not running', () => {
|
||||
test('Test ReloadAction when extension is updated when not running', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const local = aLocalExtension('a', { version: '1.0.1' });
|
||||
return instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally)
|
||||
.then(() => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
|
||||
const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' });
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Update, local: aLocalExtension('a', gallery, gallery) });
|
||||
const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' });
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Update, local: aLocalExtension('a', gallery, gallery) });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
});
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is disabled when running', () => {
|
||||
test('Test ReloadAction when extension is disabled when running', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), extensionLocation: URI.file('pub.a') }]);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const local = aLocalExtension('a');
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal().then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
return workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally)
|
||||
.then(() => testObject.update())
|
||||
.then(() => {
|
||||
assert.ok(testObject.enabled);
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
assert.equal('Please reload Azure Data Studio to disable this extension.', testObject.tooltip);
|
||||
});
|
||||
});
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally);
|
||||
await testObject.update();
|
||||
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Please reload Azure Data Studio to disable this extension.', testObject.tooltip); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension enablement is toggled when running', () => {
|
||||
test('Test ReloadAction when extension enablement is toggled when running', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.a'), version: '1.0.0', extensionLocation: URI.file('pub.a') }]);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const local = aLocalExtension('a');
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal().
|
||||
then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
return workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally)
|
||||
.then(() => workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally))
|
||||
.then(() => assert.ok(!testObject.enabled));
|
||||
});
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally);
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is enabled when not running', () => {
|
||||
test('Test ReloadAction when extension is enabled when not running', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const local = aLocalExtension('a');
|
||||
return instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally)
|
||||
.then(() => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
return workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally)
|
||||
.then(() => testObject.update())
|
||||
.then(() => {
|
||||
assert.ok(testObject.enabled);
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
assert.equal('Please reload Azure Data Studio to enable this extension.', testObject.tooltip);
|
||||
});
|
||||
});
|
||||
});
|
||||
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally);
|
||||
await testObject.update();
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Please reload Azure Data Studio to enable this extension.', testObject.tooltip); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension enablement is toggled when not running', () => {
|
||||
test('Test ReloadAction when extension enablement is toggled when not running', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const local = aLocalExtension('a');
|
||||
return instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally)
|
||||
.then(() => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
return workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally)
|
||||
.then(() => workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally))
|
||||
.then(() => assert.ok(!testObject.enabled));
|
||||
});
|
||||
});
|
||||
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally);
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.DisabledGlobally);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is updated when not running and enabled', () => {
|
||||
test('Test ReloadAction when extension is updated when not running and enabled', async () => {
|
||||
instantiationService.stubPromise(IExtensionService, 'getExtensions', [{ identifier: new ExtensionIdentifier('pub.b'), extensionLocation: URI.file('pub.b') }]);
|
||||
const local = aLocalExtension('a', { version: '1.0.1' });
|
||||
return instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally)
|
||||
.then(() => {
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
return workbenchService.queryLocal()
|
||||
.then(extensions => {
|
||||
testObject.extension = extensions[0];
|
||||
await instantiationService.get(IExtensionEnablementService).setEnablement([local], EnablementState.DisabledGlobally);
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
const workbenchService = instantiationService.get(IExtensionsWorkbenchService);
|
||||
instantiationService.stubPromise(IExtensionManagementService, 'getInstalled', [local]);
|
||||
const extensions = await workbenchService.queryLocal();
|
||||
testObject.extension = extensions[0];
|
||||
|
||||
const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' });
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, gallery) });
|
||||
return workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally)
|
||||
.then(() => testObject.update())
|
||||
.then(() => {
|
||||
assert.ok(testObject.enabled);
|
||||
// {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
assert.equal('Please reload Azure Data Studio to enable this extension.', testObject.tooltip);
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
const gallery = aGalleryExtension('a', { identifier: local.identifier, version: '1.0.2' });
|
||||
installEvent.fire({ identifier: gallery.identifier, gallery });
|
||||
didInstallEvent.fire({ identifier: gallery.identifier, gallery, operation: InstallOperation.Install, local: aLocalExtension('a', gallery, gallery) });
|
||||
await workbenchService.setEnablement(extensions[0], EnablementState.EnabledGlobally);
|
||||
await testObject.update();
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal('Please reload Azure Data Studio to enable this extension.', testObject.tooltip); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when a localization extension is newly installed', async () => {
|
||||
@@ -1358,6 +1344,146 @@ suite('ExtensionsActions Test', () => {
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is not installed but extension from different server is installed and running', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a') });
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), createExtensionManagementService([remoteExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
const runningExtensions = [ExtensionsActions.toExtensionDescription(remoteExtension)];
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve(runningExtensions),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.localExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when extension is uninstalled but extension from different server is installed and running', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a') });
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
const localExtensionManagementService = createExtensionManagementService([localExtension]);
|
||||
const uninstallEvent = new Emitter<IExtensionIdentifier>();
|
||||
const onDidUninstallEvent = new Emitter<{ identifier: IExtensionIdentifier }>();
|
||||
localExtensionManagementService.onUninstallExtension = uninstallEvent.event;
|
||||
localExtensionManagementService.onDidUninstallExtension = onDidUninstallEvent.event;
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, localExtensionManagementService, createExtensionManagementService([remoteExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
const runningExtensions = [ExtensionsActions.toExtensionDescription(remoteExtension)];
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve(runningExtensions),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.localExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
uninstallEvent.fire(localExtension.identifier);
|
||||
didUninstallEvent.fire({ identifier: localExtension.identifier });
|
||||
|
||||
assert.ok(!testObject.enabled);
|
||||
});
|
||||
|
||||
test('Test ReloadAction when workspace extension is disabled on local server and installed in remote server', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const remoteExtensionManagementService = createExtensionManagementService([]);
|
||||
const onDidInstallEvent = new Emitter<DidInstallExtensionEvent>();
|
||||
remoteExtensionManagementService.onDidInstallExtension = onDidInstallEvent.event;
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a') });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, createExtensionManagementService([localExtension]), remoteExtensionManagementService);
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve([]),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.localExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
onDidInstallEvent.fire({ identifier: remoteExtension.identifier, local: remoteExtension, operation: InstallOperation.Install });
|
||||
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal(testObject.tooltip, 'Please reload Azure Data Studio to enable this extension.'); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test ReloadAction when ui extension is disabled on remote server and installed in local server', async () => {
|
||||
// multi server setup
|
||||
const gallery = aGalleryExtension('a');
|
||||
const localExtensionManagementService = createExtensionManagementService([]);
|
||||
const onDidInstallEvent = new Emitter<DidInstallExtensionEvent>();
|
||||
localExtensionManagementService.onDidInstallExtension = onDidInstallEvent.event;
|
||||
const remoteExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a').with({ scheme: Schemas.vscodeRemote }) });
|
||||
const extensionManagementServerService = aMultiExtensionManagementServerService(instantiationService, localExtensionManagementService, createExtensionManagementService([remoteExtension]));
|
||||
instantiationService.stub(IExtensionManagementServerService, extensionManagementServerService);
|
||||
instantiationService.stub(IExtensionEnablementService, new TestExtensionEnablementService(instantiationService));
|
||||
const workbenchService: IExtensionsWorkbenchService = instantiationService.createInstance(ExtensionsWorkbenchService);
|
||||
instantiationService.set(IExtensionsWorkbenchService, workbenchService);
|
||||
|
||||
const onDidChangeExtensionsEmitter: Emitter<void> = new Emitter<void>();
|
||||
instantiationService.stub(IExtensionService, <Partial<IExtensionService>>{
|
||||
getExtensions: () => Promise.resolve([]),
|
||||
onDidChangeExtensions: onDidChangeExtensionsEmitter.event,
|
||||
canAddExtension: (extension) => false
|
||||
});
|
||||
const testObject: ExtensionsActions.ReloadAction = instantiationService.createInstance(ExtensionsActions.ReloadAction);
|
||||
instantiationService.createInstance(ExtensionContainers, [testObject]);
|
||||
instantiationService.stubPromise(IExtensionGalleryService, 'query', aPage(gallery));
|
||||
|
||||
await workbenchService.queryGallery(CancellationToken.None);
|
||||
const extensions = await workbenchService.queryLocal(extensionManagementServerService.remoteExtensionManagementServer!);
|
||||
testObject.extension = extensions[0];
|
||||
assert.ok(testObject.extension);
|
||||
assert.ok(!testObject.enabled);
|
||||
|
||||
const localExtension = aLocalExtension('a', { extensionKind: 'ui' }, { location: URI.file('pub.a') });
|
||||
onDidInstallEvent.fire({ identifier: localExtension.identifier, local: localExtension, operation: InstallOperation.Install });
|
||||
|
||||
assert.ok(testObject.enabled);
|
||||
assert.equal(testObject.tooltip, 'Please reload Azure Data Studio to enable this extension.'); // {{SQL CARBON EDIT}} - replace Visual Studio Code with Azure Data Studio
|
||||
});
|
||||
|
||||
test('Test remote install action is enabled for local workspace extension', async () => {
|
||||
// multi server setup
|
||||
const localWorkspaceExtension = aLocalExtension('a', { extensionKind: 'workspace' }, { location: URI.file(`pub.a`) });
|
||||
|
||||
@@ -533,8 +533,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
|
||||
id: OpenGlobalKeybindingsFileAction.ID,
|
||||
title: OpenGlobalKeybindingsFileAction.LABEL,
|
||||
iconLocation: {
|
||||
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/edit-json-light.svg`)),
|
||||
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/edit-json-dark.svg`))
|
||||
light: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg`)),
|
||||
dark: URI.parse(require.toUrl(`vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg`))
|
||||
}
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_KEYBINDINGS_EDITOR),
|
||||
@@ -817,8 +817,8 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
|
||||
id: SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON,
|
||||
title: nls.localize('openSettingsJson', "Open Settings (JSON)"),
|
||||
iconLocation: {
|
||||
dark: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/edit-json-dark.svg')),
|
||||
light: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/edit-json-light.svg'))
|
||||
dark: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/preferences-editor-dark.svg')),
|
||||
light: URI.parse(require.toUrl('vs/workbench/contrib/preferences/browser/media/preferences-editor-light.svg'))
|
||||
}
|
||||
},
|
||||
group: 'navigation',
|
||||
|
||||
@@ -1154,7 +1154,7 @@ abstract class AbstractSettingsEditorContribution extends Disposable implements
|
||||
abstract getId(): string;
|
||||
}
|
||||
|
||||
class DefaultSettingsEditorContribution extends AbstractSettingsEditorContribution implements ISettingsEditorContribution {
|
||||
export class DefaultSettingsEditorContribution extends AbstractSettingsEditorContribution implements ISettingsEditorContribution {
|
||||
|
||||
static readonly ID: string = 'editor.contrib.defaultsettings';
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ConfigurationTarget, IConfigurationService, overrideIdentifierFromKey } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, Extensions as ConfigurationExtensions, IConfigurationPropertySchema, IConfigurationRegistry, IConfigurationNode } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
@@ -29,6 +29,8 @@ import { RangeHighlightDecorations } from 'vs/workbench/browser/parts/editor/ran
|
||||
import { DefaultSettingsHeaderWidget, EditPreferenceWidget, SettingsGroupTitleWidget, SettingsHeaderWidget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets';
|
||||
import { IFilterResult, IPreferencesEditorModel, IPreferencesService, ISetting, ISettingsEditorModel, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { DefaultSettingsEditorModel, SettingsEditorModel, WorkspaceConfigurationEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels';
|
||||
import { IMarkerService, IMarkerData, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
export interface IPreferencesRenderer<T> extends IDisposable {
|
||||
readonly preferencesModel: IPreferencesEditorModel<T>;
|
||||
@@ -65,6 +67,8 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
|
||||
private readonly _onUpdatePreference = this._register(new Emitter<{ key: string, value: any, source: IIndexedSetting }>());
|
||||
readonly onUpdatePreference: Event<{ key: string, value: any, source: IIndexedSetting }> = this._onUpdatePreference.event;
|
||||
|
||||
private unsupportedSettingsRenderer: UnsupportedSettingsRenderer;
|
||||
|
||||
private filterResult: IFilterResult | undefined;
|
||||
|
||||
constructor(protected editor: ICodeEditor, readonly preferencesModel: SettingsEditorModel,
|
||||
@@ -78,7 +82,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
|
||||
this.editSettingActionRenderer = this._register(this.instantiationService.createInstance(EditSettingRenderer, this.editor, this.preferencesModel, this.settingHighlighter));
|
||||
this._register(this.editSettingActionRenderer.onUpdateSetting(({ key, value, source }) => this._updatePreference(key, value, source)));
|
||||
this._register(this.editor.getModel()!.onDidChangeContent(() => this.modelChangeDelayer.trigger(() => this.onModelChanged())));
|
||||
|
||||
this.unsupportedSettingsRenderer = this._register(instantiationService.createInstance(UnsupportedSettingsRenderer, editor, preferencesModel));
|
||||
}
|
||||
|
||||
getAssociatedPreferencesModel(): IPreferencesEditorModel<ISetting> {
|
||||
@@ -102,6 +106,7 @@ export class UserSettingsRenderer extends Disposable implements IPreferencesRend
|
||||
if (this.filterResult) {
|
||||
this.filterPreferences(this.filterResult);
|
||||
}
|
||||
this.unsupportedSettingsRenderer.render();
|
||||
}
|
||||
|
||||
private _updatePreference(key: string, value: any, source: IIndexedSetting): void {
|
||||
@@ -946,6 +951,151 @@ class SettingHighlighter extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
class UnsupportedSettingsRenderer extends Disposable {
|
||||
|
||||
private renderingDelayer: Delayer<void> = new Delayer<void>(200);
|
||||
|
||||
constructor(
|
||||
private editor: ICodeEditor,
|
||||
private settingsEditorModel: SettingsEditorModel,
|
||||
@IMarkerService private markerService: IMarkerService,
|
||||
@IWorkbenchEnvironmentService private workbenchEnvironmentService: IWorkbenchEnvironmentService,
|
||||
) {
|
||||
super();
|
||||
this._register(this.editor.getModel()!.onDidChangeContent(() => this.renderingDelayer.trigger(() => this.render())));
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
const markerData: IMarkerData[] = this.generateMarkerData();
|
||||
if (markerData.length) {
|
||||
this.markerService.changeOne('preferencesEditor', this.settingsEditorModel.uri, markerData);
|
||||
} else {
|
||||
this.markerService.remove('preferencesEditor', [this.settingsEditorModel.uri]);
|
||||
}
|
||||
}
|
||||
|
||||
private generateMarkerData(): IMarkerData[] {
|
||||
const markerData: IMarkerData[] = [];
|
||||
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).getConfigurationProperties();
|
||||
for (const settingsGroup of this.settingsEditorModel.settingsGroups) {
|
||||
for (const section of settingsGroup.sections) {
|
||||
for (const setting of section.settings) {
|
||||
const configuration = configurationRegistry[setting.key];
|
||||
if (configuration) {
|
||||
switch (this.settingsEditorModel.configurationTarget) {
|
||||
case ConfigurationTarget.USER_LOCAL:
|
||||
this.handleLocalUserConfiguration(setting, configuration, markerData);
|
||||
break;
|
||||
case ConfigurationTarget.USER_REMOTE:
|
||||
this.handleRemoteUserConfiguration(setting, configuration, markerData);
|
||||
break;
|
||||
case ConfigurationTarget.WORKSPACE:
|
||||
this.handleWorkspaceConfiguration(setting, configuration, markerData);
|
||||
break;
|
||||
case ConfigurationTarget.WORKSPACE_FOLDER:
|
||||
this.handleWorkspaceFolderConfiguration(setting, configuration, markerData);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
markerData.push({
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
startLineNumber: setting.keyRange.startLineNumber,
|
||||
startColumn: setting.keyRange.startColumn,
|
||||
endLineNumber: setting.valueRange.endLineNumber,
|
||||
endColumn: setting.valueRange.endColumn,
|
||||
message: nls.localize('unknown configuration setting', "Unknown Configuration Setting")
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return markerData;
|
||||
}
|
||||
|
||||
private handleLocalUserConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void {
|
||||
if (this.workbenchEnvironmentService.configuration.remote && configuration.scope === ConfigurationScope.MACHINE) {
|
||||
markerData.push({
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
startLineNumber: setting.keyRange.startLineNumber,
|
||||
startColumn: setting.keyRange.startColumn,
|
||||
endLineNumber: setting.valueRange.endLineNumber,
|
||||
endColumn: setting.valueRange.endColumn,
|
||||
message: nls.localize('unsupportedRemoteMachineSetting', "This setting can be applied only in remote machine settings")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private handleRemoteUserConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void {
|
||||
if (configuration.scope === ConfigurationScope.APPLICATION) {
|
||||
markerData.push(this.generateUnsupportedApplicationSettingMarker(setting));
|
||||
}
|
||||
}
|
||||
|
||||
private handleWorkspaceConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void {
|
||||
if (configuration.scope === ConfigurationScope.APPLICATION) {
|
||||
markerData.push(this.generateUnsupportedApplicationSettingMarker(setting));
|
||||
}
|
||||
|
||||
if (configuration.scope === ConfigurationScope.MACHINE) {
|
||||
markerData.push(this.generateUnsupportedMachineSettingMarker(setting));
|
||||
}
|
||||
}
|
||||
|
||||
private handleWorkspaceFolderConfiguration(setting: ISetting, configuration: IConfigurationNode, markerData: IMarkerData[]): void {
|
||||
if (configuration.scope === ConfigurationScope.APPLICATION) {
|
||||
markerData.push(this.generateUnsupportedApplicationSettingMarker(setting));
|
||||
}
|
||||
|
||||
if (configuration.scope === ConfigurationScope.MACHINE) {
|
||||
markerData.push(this.generateUnsupportedMachineSettingMarker(setting));
|
||||
}
|
||||
|
||||
if (configuration.scope === ConfigurationScope.WINDOW) {
|
||||
markerData.push({
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
startLineNumber: setting.keyRange.startLineNumber,
|
||||
startColumn: setting.keyRange.startColumn,
|
||||
endLineNumber: setting.valueRange.endLineNumber,
|
||||
endColumn: setting.valueRange.endColumn,
|
||||
message: nls.localize('unsupportedWindowSetting', "This setting cannot be applied now. It will be applied when you open this folder directly.")
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private generateUnsupportedApplicationSettingMarker(setting: ISetting): IMarkerData {
|
||||
return {
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
startLineNumber: setting.keyRange.startLineNumber,
|
||||
startColumn: setting.keyRange.startColumn,
|
||||
endLineNumber: setting.keyRange.endLineNumber,
|
||||
endColumn: setting.keyRange.endColumn,
|
||||
message: nls.localize('unsupportedApplicationSetting', "This setting can be applied only in application user settings")
|
||||
};
|
||||
}
|
||||
|
||||
private generateUnsupportedMachineSettingMarker(setting: ISetting): IMarkerData {
|
||||
return {
|
||||
severity: MarkerSeverity.Hint,
|
||||
tags: [MarkerTag.Unnecessary],
|
||||
startLineNumber: setting.keyRange.startLineNumber,
|
||||
startColumn: setting.keyRange.startColumn,
|
||||
endLineNumber: setting.valueRange.endLineNumber,
|
||||
endColumn: setting.valueRange.endColumn,
|
||||
message: nls.localize('unsupportedMachineSetting', "This setting can be applied only in user settings")
|
||||
};
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.markerService.remove('preferencesEditor', [this.settingsEditorModel.uri]);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class WorkspaceConfigurationRenderer extends Disposable {
|
||||
|
||||
private decorationIds: string[] = [];
|
||||
|
||||
@@ -24,13 +24,13 @@ import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/plat
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc';
|
||||
import { DownloadServiceChannel } from 'vs/platform/download/node/downloadIpc';
|
||||
import { DownloadServiceChannel } from 'vs/platform/download/common/downloadIpc';
|
||||
import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc';
|
||||
import { ipcRenderer as ipc } from 'electron';
|
||||
import { IDiagnosticInfoOptions, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IProgressService, IProgress, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { PersistenConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
@@ -38,6 +38,7 @@ import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions';
|
||||
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { RemoteConnectionState } from 'vs/workbench/browser/contextkeys';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
|
||||
const WINDOW_ACTIONS_COMMAND_ID = 'remote.showActions';
|
||||
const CLOSE_REMOTE_COMMAND_ID = 'remote.closeRemote';
|
||||
@@ -100,13 +101,13 @@ export class RemoteWindowActiveIndicator extends Disposable implements IWorkbenc
|
||||
if (connection) {
|
||||
this._register(connection.onDidStateChange((e) => {
|
||||
switch (e.type) {
|
||||
case PersistenConnectionEventType.ConnectionLost:
|
||||
case PersistenConnectionEventType.ReconnectionPermanentFailure:
|
||||
case PersistenConnectionEventType.ReconnectionRunning:
|
||||
case PersistenConnectionEventType.ReconnectionWait:
|
||||
case PersistentConnectionEventType.ConnectionLost:
|
||||
case PersistentConnectionEventType.ReconnectionPermanentFailure:
|
||||
case PersistentConnectionEventType.ReconnectionRunning:
|
||||
case PersistentConnectionEventType.ReconnectionWait:
|
||||
this.setDisconnected(true);
|
||||
break;
|
||||
case PersistenConnectionEventType.ConnectionGain:
|
||||
case PersistentConnectionEventType.ConnectionGain:
|
||||
this.setDisconnected(false);
|
||||
break;
|
||||
}
|
||||
@@ -215,12 +216,13 @@ class RemoteChannelsContribution implements IWorkbenchContribution {
|
||||
constructor(
|
||||
@ILogService logService: ILogService,
|
||||
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
|
||||
@IDialogService dialogService: IDialogService
|
||||
@IDialogService dialogService: IDialogService,
|
||||
@IDownloadService downloadService: IDownloadService
|
||||
) {
|
||||
const connection = remoteAgentService.getConnection();
|
||||
if (connection) {
|
||||
connection.registerChannel('dialog', new DialogChannel(dialogService));
|
||||
connection.registerChannel('download', new DownloadServiceChannel());
|
||||
connection.registerChannel('download', new DownloadServiceChannel(downloadService));
|
||||
connection.registerChannel('loglevel', new LogLevelSetterChannel(logService));
|
||||
}
|
||||
}
|
||||
@@ -296,7 +298,7 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
|
||||
currentTimer = null;
|
||||
}
|
||||
switch (e.type) {
|
||||
case PersistenConnectionEventType.ConnectionLost:
|
||||
case PersistentConnectionEventType.ConnectionLost:
|
||||
if (!currentProgressPromiseResolve) {
|
||||
let promise = new Promise<void>((resolve) => currentProgressPromiseResolve = resolve);
|
||||
progressService!.withProgress(
|
||||
@@ -313,13 +315,13 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
|
||||
|
||||
progressReporter!.report(nls.localize('connectionLost', "Connection Lost"));
|
||||
break;
|
||||
case PersistenConnectionEventType.ReconnectionWait:
|
||||
case PersistentConnectionEventType.ReconnectionWait:
|
||||
currentTimer = new ReconnectionTimer(progressReporter!, Date.now() + 1000 * e.durationSeconds);
|
||||
break;
|
||||
case PersistenConnectionEventType.ReconnectionRunning:
|
||||
case PersistentConnectionEventType.ReconnectionRunning:
|
||||
progressReporter!.report(nls.localize('reconnectionRunning', "Attempting to reconnect..."));
|
||||
break;
|
||||
case PersistenConnectionEventType.ReconnectionPermanentFailure:
|
||||
case PersistentConnectionEventType.ReconnectionPermanentFailure:
|
||||
currentProgressPromiseResolve!();
|
||||
currentProgressPromiseResolve = null;
|
||||
progressReporter = null;
|
||||
@@ -331,7 +333,7 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
|
||||
}
|
||||
});
|
||||
break;
|
||||
case PersistenConnectionEventType.ConnectionGain:
|
||||
case PersistentConnectionEventType.ConnectionGain:
|
||||
currentProgressPromiseResolve!();
|
||||
currentProgressPromiseResolve = null;
|
||||
progressReporter = null;
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
|
||||
/**
|
||||
* Webview editor overlay that creates and destroys the underlying webview as needed.
|
||||
*/
|
||||
export class DynamicWebviewEditorOverlay extends Disposable implements WebviewEditorOverlay {
|
||||
|
||||
private readonly _pendingMessages = new Set<any>();
|
||||
private readonly _webview = this._register(new MutableDisposable<WebviewElement>());
|
||||
private readonly _webviewEvents = this._register(new DisposableStore());
|
||||
|
||||
private _html: string = '';
|
||||
private _initialScrollProgress: number = 0;
|
||||
private _state: string | undefined = undefined;
|
||||
private _owner: any = undefined;
|
||||
|
||||
public constructor(
|
||||
private readonly id: string,
|
||||
public readonly options: WebviewOptions,
|
||||
private _contentOptions: WebviewContentOptions,
|
||||
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
|
||||
@IWebviewService private readonly _webviewService: IWebviewService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._register(toDisposable(() => this.container.remove()));
|
||||
}
|
||||
|
||||
@memoize
|
||||
public get container() {
|
||||
const container = document.createElement('div');
|
||||
container.id = `webview-${this.id}`;
|
||||
this._layoutService.getContainer(Parts.EDITOR_PART).appendChild(container);
|
||||
return container;
|
||||
}
|
||||
|
||||
public claim(owner: any) {
|
||||
this._owner = owner;
|
||||
this.show();
|
||||
}
|
||||
|
||||
public release(owner: any) {
|
||||
if (this._owner !== owner) {
|
||||
return;
|
||||
}
|
||||
this._owner = undefined;
|
||||
this.container.style.visibility = 'hidden';
|
||||
if (!this.options.retainContextWhenHidden) {
|
||||
this._webview.clear();
|
||||
this._webviewEvents.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private show() {
|
||||
if (!this._webview.value) {
|
||||
const webview = this._webviewService.createWebview(this.id, this.options, this._contentOptions);
|
||||
this._webview.value = webview;
|
||||
webview.state = this._state;
|
||||
webview.html = this._html;
|
||||
if (this.options.tryRestoreScrollPosition) {
|
||||
webview.initialScrollProgress = this._initialScrollProgress;
|
||||
}
|
||||
this._webview.value.mountTo(this.container);
|
||||
this._webviewEvents.clear();
|
||||
|
||||
webview.onDidFocus(() => { this._onDidFocus.fire(); }, undefined, this._webviewEvents);
|
||||
webview.onDidClickLink(x => { this._onDidClickLink.fire(x); }, undefined, this._webviewEvents);
|
||||
webview.onMessage(x => { this._onMessage.fire(x); }, undefined, this._webviewEvents);
|
||||
|
||||
webview.onDidScroll(x => {
|
||||
this._initialScrollProgress = x.scrollYPercentage;
|
||||
this._onDidScroll.fire(x);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
webview.onDidUpdateState(state => {
|
||||
this._state = state;
|
||||
this._onDidUpdateState.fire(state);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
this._pendingMessages.forEach(msg => webview.sendMessage(msg));
|
||||
this._pendingMessages.clear();
|
||||
}
|
||||
this.container.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
public get html(): string { return this._html; }
|
||||
public set html(value: string) {
|
||||
this._html = value;
|
||||
this.withWebview(webview => webview.html = value);
|
||||
}
|
||||
|
||||
public get initialScrollProgress(): number { return this._initialScrollProgress; }
|
||||
public set initialScrollProgress(value: number) {
|
||||
this._initialScrollProgress = value;
|
||||
this.withWebview(webview => webview.initialScrollProgress = value);
|
||||
}
|
||||
|
||||
public get state(): string | undefined { return this._state; }
|
||||
public set state(value: string | undefined) {
|
||||
this._state = value;
|
||||
this.withWebview(webview => webview.state = value);
|
||||
}
|
||||
|
||||
public get contentOptions(): WebviewContentOptions { return this._contentOptions; }
|
||||
public set contentOptions(value: WebviewContentOptions) {
|
||||
this._contentOptions = value;
|
||||
this.withWebview(webview => webview.contentOptions = value);
|
||||
}
|
||||
|
||||
private readonly _onDidFocus = this._register(new Emitter<void>());
|
||||
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
|
||||
|
||||
private readonly _onDidClickLink = this._register(new Emitter<URI>());
|
||||
public readonly onDidClickLink: Event<URI> = this._onDidClickLink.event;
|
||||
|
||||
private readonly _onDidScroll = this._register(new Emitter<{ scrollYPercentage: number; }>());
|
||||
public readonly onDidScroll: Event<{ scrollYPercentage: number; }> = this._onDidScroll.event;
|
||||
|
||||
private readonly _onDidUpdateState = this._register(new Emitter<string | undefined>());
|
||||
public readonly onDidUpdateState: Event<string | undefined> = this._onDidUpdateState.event;
|
||||
|
||||
private readonly _onMessage = this._register(new Emitter<any>());
|
||||
public readonly onMessage: Event<any> = this._onMessage.event;
|
||||
|
||||
sendMessage(data: any): void {
|
||||
if (this._webview.value) {
|
||||
this._webview.value.sendMessage(data);
|
||||
} else {
|
||||
this._pendingMessages.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean): void {
|
||||
this._contentOptions = options;
|
||||
this._html = html;
|
||||
this.withWebview(webview => {
|
||||
webview.update(html, options, retainContextWhenHidden);
|
||||
});
|
||||
}
|
||||
|
||||
layout(): void { this.withWebview(webview => webview.layout()); }
|
||||
focus(): void { this.withWebview(webview => webview.focus()); }
|
||||
reload(): void { this.withWebview(webview => webview.reload()); }
|
||||
showFind(): void { this.withWebview(webview => webview.showFind()); }
|
||||
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
|
||||
|
||||
public getInnerWebview() {
|
||||
return this._webview.value;
|
||||
}
|
||||
|
||||
private withWebview(f: (webview: Webview) => void): void {
|
||||
if (this._webview.value) {
|
||||
f(this._webview.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,9 @@ export class IFrameWebview extends Disposable implements Webview {
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
) {
|
||||
super();
|
||||
if (typeof environmentService.webviewEndpoint !== 'string') {
|
||||
const useExternalEndpoint = this._configurationService.getValue<string>('webview.experimental.useExternalEndpoint');
|
||||
|
||||
if (typeof environmentService.webviewEndpoint !== 'string' && !useExternalEndpoint) {
|
||||
throw new Error('To use iframe based webviews, you must configure `environmentService.webviewEndpoint`');
|
||||
}
|
||||
|
||||
@@ -142,7 +144,9 @@ export class IFrameWebview extends Disposable implements Webview {
|
||||
}
|
||||
|
||||
private get endpoint(): string {
|
||||
const endpoint = this.environmentService.webviewEndpoint!.replace('{{uuid}}', this.id);
|
||||
const useExternalEndpoint = this._configurationService.getValue<string>('webview.experimental.useExternalEndpoint');
|
||||
const baseEndpoint = useExternalEndpoint ? 'https://{{uuid}}.vscode-webview-test.com/8fa811108f0f0524c473020ef57b6620f6c201e1' : this.environmentService.webviewEndpoint!;
|
||||
const endpoint = baseEndpoint.replace('{{uuid}}', this.id);
|
||||
if (endpoint[endpoint.length - 1] === '/') {
|
||||
return endpoint.slice(0, endpoint.length - 1);
|
||||
}
|
||||
|
||||
@@ -3,14 +3,10 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement';
|
||||
import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { DynamicWebviewEditorOverlay } from './dynamicWebviewEditorOverlay';
|
||||
|
||||
export class WebviewService implements IWebviewService {
|
||||
_serviceBrand: any;
|
||||
@@ -35,166 +31,3 @@ export class WebviewService implements IWebviewService {
|
||||
return this._instantiationService.createInstance(DynamicWebviewEditorOverlay, id, options, contentOptions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Webview editor overlay that creates and destroys the underlying webview as needed.
|
||||
*/
|
||||
class DynamicWebviewEditorOverlay extends Disposable implements WebviewEditorOverlay {
|
||||
|
||||
private readonly _pendingMessages = new Set<any>();
|
||||
private readonly _webview = this._register(new MutableDisposable<WebviewElement>());
|
||||
private readonly _webviewEvents = this._register(new DisposableStore());
|
||||
|
||||
private _html: string = '';
|
||||
private _initialScrollProgress: number = 0;
|
||||
private _state: string | undefined = undefined;
|
||||
private _owner: any = undefined;
|
||||
|
||||
public constructor(
|
||||
private readonly id: string,
|
||||
public readonly options: WebviewOptions,
|
||||
private _contentOptions: WebviewContentOptions,
|
||||
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
|
||||
@IWebviewService private readonly _webviewService: IWebviewService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._register(toDisposable(() => this.container.remove()));
|
||||
}
|
||||
|
||||
@memoize
|
||||
public get container() {
|
||||
const container = document.createElement('div');
|
||||
container.id = `webview-${this.id}`;
|
||||
this._layoutService.getContainer(Parts.EDITOR_PART).appendChild(container);
|
||||
return container;
|
||||
}
|
||||
|
||||
public claim(owner: any) {
|
||||
this._owner = owner;
|
||||
this.show();
|
||||
}
|
||||
|
||||
public release(owner: any) {
|
||||
if (this._owner !== owner) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._owner = undefined;
|
||||
this.container.style.visibility = 'hidden';
|
||||
if (!this.options.retainContextWhenHidden) {
|
||||
this._webview.clear();
|
||||
this._webviewEvents.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private show() {
|
||||
if (!this._webview.value) {
|
||||
const webview = this._webviewService.createWebview(this.id, this.options, this._contentOptions);
|
||||
this._webview.value = webview;
|
||||
webview.state = this._state;
|
||||
webview.html = this._html;
|
||||
|
||||
if (this.options.tryRestoreScrollPosition) {
|
||||
webview.initialScrollProgress = this._initialScrollProgress;
|
||||
}
|
||||
|
||||
this._webview.value.mountTo(this.container);
|
||||
|
||||
this._webviewEvents.clear();
|
||||
|
||||
webview.onDidFocus(() => {
|
||||
this._onDidFocus.fire();
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
webview.onDidClickLink(x => {
|
||||
this._onDidClickLink.fire(x);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
webview.onDidScroll(x => {
|
||||
this._initialScrollProgress = x.scrollYPercentage;
|
||||
this._onDidScroll.fire(x);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
webview.onDidUpdateState(state => {
|
||||
this._state = state;
|
||||
this._onDidUpdateState.fire(state);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
webview.onMessage(x => {
|
||||
this._onMessage.fire(x);
|
||||
}, undefined, this._webviewEvents);
|
||||
|
||||
this._pendingMessages.forEach(msg => webview.sendMessage(msg));
|
||||
this._pendingMessages.clear();
|
||||
}
|
||||
this.container.style.visibility = 'visible';
|
||||
}
|
||||
|
||||
public get html(): string { return this._html; }
|
||||
public set html(value: string) {
|
||||
this._html = value;
|
||||
this.withWebview(webview => webview.html = value);
|
||||
}
|
||||
|
||||
public get initialScrollProgress(): number { return this._initialScrollProgress; }
|
||||
public set initialScrollProgress(value: number) {
|
||||
this._initialScrollProgress = value;
|
||||
this.withWebview(webview => webview.initialScrollProgress = value);
|
||||
}
|
||||
|
||||
public get state(): string | undefined { return this._state; }
|
||||
public set state(value: string | undefined) {
|
||||
this._state = value;
|
||||
this.withWebview(webview => webview.state = value);
|
||||
}
|
||||
|
||||
public get contentOptions(): WebviewContentOptions { return this._contentOptions; }
|
||||
public set contentOptions(value: WebviewContentOptions) {
|
||||
this._contentOptions = value;
|
||||
this.withWebview(webview => webview.contentOptions = value);
|
||||
}
|
||||
|
||||
private readonly _onDidFocus = this._register(new Emitter<void>());
|
||||
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
|
||||
|
||||
private readonly _onDidClickLink = this._register(new Emitter<URI>());
|
||||
public readonly onDidClickLink: Event<URI> = this._onDidClickLink.event;
|
||||
|
||||
private readonly _onDidScroll = this._register(new Emitter<{ scrollYPercentage: number; }>());
|
||||
public readonly onDidScroll: Event<{ scrollYPercentage: number; }> = this._onDidScroll.event;
|
||||
|
||||
private readonly _onDidUpdateState = this._register(new Emitter<string | undefined>());
|
||||
public readonly onDidUpdateState: Event<string | undefined> = this._onDidUpdateState.event;
|
||||
|
||||
private readonly _onMessage = this._register(new Emitter<any>());
|
||||
public readonly onMessage: Event<any> = this._onMessage.event;
|
||||
|
||||
sendMessage(data: any): void {
|
||||
if (this._webview.value) {
|
||||
this._webview.value.sendMessage(data);
|
||||
} else {
|
||||
this._pendingMessages.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean): void {
|
||||
this._contentOptions = options;
|
||||
this._html = html;
|
||||
this.withWebview(webview => {
|
||||
webview.update(html, options, retainContextWhenHidden);
|
||||
});
|
||||
}
|
||||
|
||||
layout(): void { this.withWebview(webview => webview.layout()); }
|
||||
focus(): void { this.withWebview(webview => webview.focus()); }
|
||||
reload(): void { this.withWebview(webview => webview.reload()); }
|
||||
showFind(): void { this.withWebview(webview => webview.showFind()); }
|
||||
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
|
||||
|
||||
private withWebview(f: (webview: Webview) => void): void {
|
||||
if (this._webview.value) {
|
||||
f(this._webview.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,6 +97,8 @@ export interface WebviewEditorOverlay extends Webview {
|
||||
|
||||
claim(owner: any): void;
|
||||
release(owner: any): void;
|
||||
|
||||
getInnerWebview(): Webview | undefined;
|
||||
}
|
||||
|
||||
export const webviewDeveloperCategory = nls.localize('developer', "Developer");
|
||||
|
||||
@@ -15,9 +15,9 @@ import { Extensions as ActionExtensions, IWorkbenchActionRegistry } from 'vs/wor
|
||||
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
|
||||
import { IWebviewService, webviewDeveloperCategory } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import * as webviewCommands from 'vs/workbench/contrib/webview/electron-browser/webviewCommands';
|
||||
import { WebviewService } from 'vs/workbench/contrib/webview/electron-browser/webviewService';
|
||||
import { ElectronWebviewService } from 'vs/workbench/contrib/webview/electron-browser/webviewService';
|
||||
|
||||
registerSingleton(IWebviewService, WebviewService, true);
|
||||
registerSingleton(IWebviewService, ElectronWebviewService, true);
|
||||
|
||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Command, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { ElectronWebviewBasedWebview } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
|
||||
import { WebviewEditorOverlay } from 'vs/workbench/contrib/webview/common/webview';
|
||||
|
||||
export class OpenWebviewDeveloperToolsAction extends Action {
|
||||
static readonly ID = 'workbench.action.webview.openDeveloperTools';
|
||||
@@ -92,6 +93,11 @@ function withActiveWebviewBasedWebview(accessor: ServicesAccessor, f: (webview:
|
||||
webViewEditor.withWebview(webview => {
|
||||
if (webview instanceof ElectronWebviewBasedWebview) {
|
||||
f(webview);
|
||||
} else if ((webview as WebviewEditorOverlay).getInnerWebview) {
|
||||
const innerWebview = (webview as WebviewEditorOverlay).getInnerWebview();
|
||||
if (innerWebview instanceof ElectronWebviewBasedWebview) {
|
||||
f(innerWebview);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,25 +3,39 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { WebviewService as BrowserWebviewService } from 'vs/workbench/contrib/webview/browser/webviewService';
|
||||
import { IWebviewService, WebviewContentOptions, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { DynamicWebviewEditorOverlay } from 'vs/workbench/contrib/webview/browser/dynamicWebviewEditorOverlay';
|
||||
import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement';
|
||||
import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
|
||||
import { ElectronWebviewBasedWebview } from 'vs/workbench/contrib/webview/electron-browser/webviewElement';
|
||||
|
||||
export class WebviewService extends BrowserWebviewService implements IWebviewService {
|
||||
export class ElectronWebviewService implements IWebviewService {
|
||||
_serviceBrand: any;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
) {
|
||||
super(instantiationService);
|
||||
}
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
) { }
|
||||
|
||||
createWebview(
|
||||
_id: string,
|
||||
id: string,
|
||||
options: WebviewOptions,
|
||||
contentOptions: WebviewContentOptions
|
||||
): WebviewElement {
|
||||
return this.instantiationService.createInstance(ElectronWebviewBasedWebview, options, contentOptions);
|
||||
const useExternalEndpoint = this._configService.getValue<string>('webview.experimental.useExternalEndpoint');
|
||||
if (useExternalEndpoint) {
|
||||
return this._instantiationService.createInstance(IFrameWebview, id, options, contentOptions);
|
||||
} else {
|
||||
return this._instantiationService.createInstance(ElectronWebviewBasedWebview, options, contentOptions);
|
||||
}
|
||||
}
|
||||
|
||||
createWebviewEditorOverlay(
|
||||
id: string,
|
||||
options: WebviewOptions,
|
||||
contentOptions: WebviewContentOptions,
|
||||
): WebviewEditorOverlay {
|
||||
return this._instantiationService.createInstance(DynamicWebviewEditorOverlay, id, options, contentOptions);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user