mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 02:32:35 -05:00
Merge from vscode 70dc55955d586ebd427658b43cdb344f2047f9c2 (#6789)
This commit is contained in:
@@ -22,10 +22,16 @@ import { WebWorkerExtensionHostStarter } from 'vs/workbench/services/extensions/
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isWebExtension } from 'vs/workbench/services/extensions/common/extensionsUtil';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
|
||||
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null;
|
||||
private _disposables = new DisposableStore();
|
||||
private _remoteExtensionsEnvironmentData: IRemoteAgentEnvironment | null = null;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@@ -37,6 +43,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
@IProductService productService: IProductService,
|
||||
@IRemoteAgentService private readonly _remoteAgentService: IRemoteAgentService,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
@IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService,
|
||||
) {
|
||||
super(
|
||||
instantiationService,
|
||||
@@ -48,8 +55,19 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
productService,
|
||||
);
|
||||
|
||||
this._remoteExtensionsEnvironmentData = null;
|
||||
this._initialize();
|
||||
this._initFetchFileSystem();
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._disposables.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _initFetchFileSystem(): void {
|
||||
const provider = new FetchFileSystemProvider();
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.http, provider));
|
||||
this._disposables.add(this._fileService.registerProvider(Schemas.https, provider));
|
||||
}
|
||||
|
||||
private _createProvider(remoteAuthority: string): IInitDataProvider {
|
||||
@@ -84,23 +102,31 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
|
||||
protected async _scanAndHandleExtensions(): Promise<void> {
|
||||
// fetch the remote environment
|
||||
const remoteEnv = (await this._remoteAgentService.getEnvironment())!;
|
||||
let [remoteEnv, localExtensions] = await Promise.all([
|
||||
<Promise<IRemoteAgentEnvironment>>this._remoteAgentService.getEnvironment(),
|
||||
this._staticExtensions.getExtensions()
|
||||
]);
|
||||
|
||||
// enable or disable proposed API per extension
|
||||
// local: only enabled and web'ish extension
|
||||
localExtensions = localExtensions.filter(ext => this._isEnabled(ext) && isWebExtension(ext, this._configService));
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
|
||||
// remote: only enabled and none-web'ish extension
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension) && !isWebExtension(extension, this._configService));
|
||||
this._checkEnableProposedApi(remoteEnv.extensions);
|
||||
|
||||
// remove disabled extensions
|
||||
remoteEnv.extensions = remoteEnv.extensions.filter(extension => this._isEnabled(extension));
|
||||
// in case of overlap, the remote wins
|
||||
const isRemoteExtension = new Set<string>();
|
||||
remoteEnv.extensions.forEach(extension => isRemoteExtension.add(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
localExtensions = localExtensions.filter(extension => !isRemoteExtension.has(ExtensionIdentifier.toKey(extension.identifier)));
|
||||
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData = remoteEnv;
|
||||
|
||||
// this._handleExtensionPoints((<IExtensionDescription[]>[]).concat(remoteEnv.extensions).concat(localExtensions));
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions, []);
|
||||
const result = this._registry.deltaExtensions(remoteEnv.extensions.concat(localExtensions), []);
|
||||
if (result.removedDueToLooping.length > 0) {
|
||||
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
|
||||
}
|
||||
|
||||
this._doHandleExtensionPoints(this._registry.getAllExtensionDescriptions());
|
||||
}
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter {
|
||||
};
|
||||
|
||||
worker.onerror = (event) => {
|
||||
console.error(event.error);
|
||||
this._onDidExit.fire([81, event.error]);
|
||||
console.error(event.message, event.error);
|
||||
this._onDidExit.fire([81, event.message || event.error]);
|
||||
};
|
||||
|
||||
// keep for cleanup
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IFileSystemProvider, FileSystemProviderCapabilities, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileSystemProviderError, FileSystemProviderErrorCode } from 'vs/platform/files/common/files';
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { NotImplementedError } from 'vs/base/common/errors';
|
||||
|
||||
export class FetchFileSystemProvider implements IFileSystemProvider {
|
||||
|
||||
readonly capabilities = FileSystemProviderCapabilities.Readonly + FileSystemProviderCapabilities.FileReadWrite + FileSystemProviderCapabilities.PathCaseSensitive;
|
||||
readonly onDidChangeCapabilities = Event.None;
|
||||
readonly onDidChangeFile = Event.None;
|
||||
|
||||
// working implementations
|
||||
async readFile(resource: URI): Promise<Uint8Array> {
|
||||
try {
|
||||
const res = await fetch(resource.toString(true));
|
||||
if (res.status === 200) {
|
||||
return new Uint8Array(await res.arrayBuffer());
|
||||
}
|
||||
throw new FileSystemProviderError(res.statusText, FileSystemProviderErrorCode.Unknown);
|
||||
} catch (err) {
|
||||
throw new FileSystemProviderError(err, FileSystemProviderErrorCode.Unknown);
|
||||
}
|
||||
}
|
||||
|
||||
// fake implementations
|
||||
async stat(_resource: URI): Promise<IStat> {
|
||||
return {
|
||||
type: FileType.File,
|
||||
size: 0,
|
||||
mtime: 0,
|
||||
ctime: 0
|
||||
};
|
||||
}
|
||||
|
||||
watch(): IDisposable {
|
||||
return Disposable.None;
|
||||
}
|
||||
|
||||
// error implementations
|
||||
writeFile(_resource: URI, _content: Uint8Array, _opts: FileWriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
readdir(_resource: URI): Promise<[string, FileType][]> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
mkdir(_resource: URI): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
delete(_resource: URI, _opts: FileDeleteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
rename(_from: URI, _to: URI, _opts: FileOverwriteOptions): Promise<void> {
|
||||
throw new NotImplementedError();
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,7 @@ export interface IExtensionPointUser<T> {
|
||||
collector: ExtensionMessageCollector;
|
||||
}
|
||||
|
||||
export interface IExtensionPointHandler<T> {
|
||||
(extensions: IExtensionPointUser<T>[], delta: ExtensionPointUserDelta<T>): void;
|
||||
}
|
||||
export type IExtensionPointHandler<T> = (extensions: readonly IExtensionPointUser<T>[], delta: ExtensionPointUserDelta<T>) => void;
|
||||
|
||||
export interface IExtensionPoint<T> {
|
||||
name: string;
|
||||
@@ -73,7 +71,7 @@ export interface IExtensionPoint<T> {
|
||||
|
||||
export class ExtensionPointUserDelta<T> {
|
||||
|
||||
private static _toSet<T>(arr: IExtensionPointUser<T>[]): Set<string> {
|
||||
private static _toSet<T>(arr: readonly IExtensionPointUser<T>[]): Set<string> {
|
||||
const result = new Set<string>();
|
||||
for (let i = 0, len = arr.length; i < len; i++) {
|
||||
result.add(ExtensionIdentifier.toKey(arr[i].description.identifier));
|
||||
@@ -81,7 +79,7 @@ export class ExtensionPointUserDelta<T> {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static compute<T>(previous: IExtensionPointUser<T>[] | null, current: IExtensionPointUser<T>[]): ExtensionPointUserDelta<T> {
|
||||
public static compute<T>(previous: readonly IExtensionPointUser<T>[] | null, current: readonly IExtensionPointUser<T>[]): ExtensionPointUserDelta<T> {
|
||||
if (!previous || !previous.length) {
|
||||
return new ExtensionPointUserDelta<T>(current, []);
|
||||
}
|
||||
@@ -99,8 +97,8 @@ export class ExtensionPointUserDelta<T> {
|
||||
}
|
||||
|
||||
constructor(
|
||||
public readonly added: IExtensionPointUser<T>[],
|
||||
public readonly removed: IExtensionPointUser<T>[],
|
||||
public readonly added: readonly IExtensionPointUser<T>[],
|
||||
public readonly removed: readonly IExtensionPointUser<T>[],
|
||||
) { }
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtensionDescription, IExtensionManifest, ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { UriComponents, URI } from 'vs/base/common/uri';
|
||||
|
||||
export const IStaticExtensionsService = createDecorator<IStaticExtensionsService>('IStaticExtensionsService');
|
||||
|
||||
export interface IStaticExtensionsService {
|
||||
_serviceBrand: any;
|
||||
getExtensions(): Promise<IExtensionDescription[]>;
|
||||
}
|
||||
|
||||
export class StaticExtensionsService implements IStaticExtensionsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly _descriptions: IExtensionDescription[] = [];
|
||||
|
||||
constructor(staticExtensions: { packageJSON: IExtensionManifest, extensionLocation: UriComponents }[]) {
|
||||
this._descriptions = staticExtensions.map(data => <IExtensionDescription>{
|
||||
identifier: new ExtensionIdentifier(`${data.packageJSON.publisher}.${data.packageJSON.name}`),
|
||||
extensionLocation: URI.revive(data.extensionLocation),
|
||||
...data.packageJSON,
|
||||
});
|
||||
}
|
||||
|
||||
async getExtensions(): Promise<IExtensionDescription[]> {
|
||||
return this._descriptions;
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,8 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { Logger } from 'vs/workbench/services/extensions/common/extensionPoints';
|
||||
import { flatten } from 'vs/base/common/arrays';
|
||||
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
|
||||
|
||||
class DeltaExtensionsQueueItem {
|
||||
constructor(
|
||||
@@ -64,6 +66,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@ILifecycleService private readonly _lifecycleService: ILifecycleService,
|
||||
@IWindowService protected readonly _windowService: IWindowService,
|
||||
@IStaticExtensionsService private readonly _staticExtensions: IStaticExtensionsService,
|
||||
) {
|
||||
super(
|
||||
instantiationService,
|
||||
@@ -72,7 +75,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
telemetryService,
|
||||
extensionEnablementService,
|
||||
fileService,
|
||||
productService,
|
||||
productService
|
||||
);
|
||||
|
||||
if (this._extensionEnablementService.allUserExtensionsDisabled) {
|
||||
@@ -437,7 +440,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
const remoteAuthority = this._environmentService.configuration.remoteAuthority;
|
||||
const extensionHost = this._extensionHostProcessManagers[0];
|
||||
|
||||
let localExtensions = await this._extensionScanner.scannedExtensions;
|
||||
let localExtensions = flatten(await Promise.all([this._extensionScanner.scannedExtensions, this._staticExtensions.getExtensions()]));
|
||||
|
||||
// enable or disable proposed API per extension
|
||||
this._checkEnableProposedApi(localExtensions);
|
||||
@@ -463,7 +466,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
this._remoteAuthorityResolverService.setResolvedAuthorityError(remoteAuthority, err);
|
||||
|
||||
// Proceed with the local extension host
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions);
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -508,20 +511,18 @@ export class ExtensionService extends AbstractExtensionService implements IExten
|
||||
// save for remote extension's init data
|
||||
this._remoteExtensionsEnvironmentData.set(remoteAuthority, remoteEnv);
|
||||
|
||||
this._handleExtensionPoints((<IExtensionDescription[]>[]).concat(remoteEnv.extensions).concat(localExtensions));
|
||||
extensionHost.start(localExtensions.map(extension => extension.identifier));
|
||||
|
||||
await this._startLocalExtensionHost(extensionHost, remoteEnv.extensions.concat(localExtensions), localExtensions.map(extension => extension.identifier));
|
||||
} else {
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions);
|
||||
await this._startLocalExtensionHost(extensionHost, localExtensions, localExtensions.map(extension => extension.identifier));
|
||||
}
|
||||
}
|
||||
|
||||
private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, localExtensions: IExtensionDescription[]): Promise<void> {
|
||||
this._handleExtensionPoints(localExtensions);
|
||||
extensionHost.start(localExtensions.map(extension => extension.identifier).filter(id => this._registry.containsExtension(id)));
|
||||
private async _startLocalExtensionHost(extensionHost: ExtensionHostProcessManager, allExtensions: IExtensionDescription[], localExtensions: ExtensionIdentifier[]): Promise<void> {
|
||||
this._registerAndHandleExtensions(allExtensions);
|
||||
extensionHost.start(localExtensions.filter(id => this._registry.containsExtension(id)));
|
||||
}
|
||||
|
||||
private _handleExtensionPoints(allExtensions: IExtensionDescription[]): void {
|
||||
private _registerAndHandleExtensions(allExtensions: IExtensionDescription[]): void {
|
||||
const result = this._registry.deltaExtensions(allExtensions, []);
|
||||
if (result.removedDueToLooping.length > 0) {
|
||||
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
|
||||
|
||||
@@ -13,8 +13,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, Severity, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
|
||||
import { localize } from 'vs/nls';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
|
||||
@@ -26,8 +25,7 @@ export class WorkspaceWatcher extends Disposable {
|
||||
@IFileService private readonly fileService: FileService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
@INotificationService private readonly notificationService: INotificationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -73,38 +71,34 @@ export class WorkspaceWatcher extends Disposable {
|
||||
onUnexpectedError(msg);
|
||||
|
||||
// Detect if we run < .NET Framework 4.5
|
||||
if (msg.indexOf('System.MissingMethodException') >= 0 && !this.storageService.getBoolean('ignoreNetVersionError', StorageScope.WORKSPACE)) {
|
||||
if (msg.indexOf('System.MissingMethodException') >= 0) {
|
||||
this.notificationService.prompt(
|
||||
Severity.Warning,
|
||||
localize('netVersionError', "The Microsoft .NET Framework 4.5 is required. Please follow the link to install it."),
|
||||
[{
|
||||
label: localize('installNet', "Download .NET Framework 4.5"),
|
||||
run: () => window.open('https://go.microsoft.com/fwlink/?LinkId=786533')
|
||||
},
|
||||
{
|
||||
label: localize('neverShowAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store('ignoreNetVersionError', true, StorageScope.WORKSPACE)
|
||||
}],
|
||||
{ sticky: true }
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'ignoreNetVersionError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Detect if we run into ENOSPC issues
|
||||
if (msg.indexOf('ENOSPC') >= 0 && !this.storageService.getBoolean('ignoreEnospcError', StorageScope.WORKSPACE)) {
|
||||
if (msg.indexOf('ENOSPC') >= 0) {
|
||||
this.notificationService.prompt(
|
||||
Severity.Warning,
|
||||
localize('enospcError', "Unable to watch for file changes in this large workspace. Please follow the instructions link to resolve this issue."),
|
||||
[{
|
||||
label: localize('learnMore', "Instructions"),
|
||||
run: () => window.open('https://go.microsoft.com/fwlink/?linkid=867693')
|
||||
},
|
||||
{
|
||||
label: localize('neverShowAgain', "Don't Show Again"),
|
||||
isSecondary: true,
|
||||
run: () => this.storageService.store('ignoreEnospcError', true, StorageScope.WORKSPACE)
|
||||
}],
|
||||
{ sticky: true }
|
||||
{
|
||||
sticky: true,
|
||||
neverShowAgain: { id: 'ignoreEnospcError', isSecondary: true, scope: NeverShowAgainScope.WORKSPACE }
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -157,4 +151,4 @@ export class WorkspaceWatcher extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored);
|
||||
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(WorkspaceWatcher, LifecyclePhase.Restored);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationService, INotification, INotificationHandle, Severity, NotificationMessage, INotificationActions, IPromptChoice, IPromptOptions, IStatusMessageOptions, NoOpNotification, NeverShowAgainScope } from 'vs/platform/notification/common/notification';
|
||||
import { INotificationsModel, NotificationsModel, ChoiceAction } from 'vs/workbench/common/notifications';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -63,11 +63,12 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
// Handle neverShowAgain option accordingly
|
||||
let handle: INotificationHandle;
|
||||
if (notification.neverShowAgain) {
|
||||
const scope = notification.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL;
|
||||
|
||||
// If the user already picked to not show the notification
|
||||
// again, we return with a no-op notification here
|
||||
const id = notification.neverShowAgain.id;
|
||||
if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) {
|
||||
if (this.storageService.getBoolean(id, scope)) {
|
||||
return new NoOpNotification();
|
||||
}
|
||||
|
||||
@@ -80,7 +81,7 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
handle.close();
|
||||
|
||||
// Remember choice
|
||||
this.storageService.store(id, true, StorageScope.GLOBAL);
|
||||
this.storageService.store(id, true, scope);
|
||||
|
||||
return Promise.resolve();
|
||||
}));
|
||||
@@ -110,17 +111,18 @@ export class NotificationService extends Disposable implements INotificationServ
|
||||
|
||||
// Handle neverShowAgain option accordingly
|
||||
if (options && options.neverShowAgain) {
|
||||
const scope = options.neverShowAgain.scope === NeverShowAgainScope.WORKSPACE ? StorageScope.WORKSPACE : StorageScope.GLOBAL;
|
||||
|
||||
// If the user already picked to not show the notification
|
||||
// again, we return with a no-op notification here
|
||||
const id = options.neverShowAgain.id;
|
||||
if (this.storageService.getBoolean(id, StorageScope.GLOBAL)) {
|
||||
if (this.storageService.getBoolean(id, scope)) {
|
||||
return new NoOpNotification();
|
||||
}
|
||||
|
||||
const neverShowAgainChoice = {
|
||||
label: nls.localize('neverShowAgain', "Don't Show Again"),
|
||||
run: () => this.storageService.store(id, true, StorageScope.GLOBAL),
|
||||
run: () => this.storageService.store(id, true, scope),
|
||||
isSecondary: options.neverShowAgain.isSecondary
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import * as Json from 'vs/base/common/json';
|
||||
import { ExtensionData, IThemeExtensionPoint, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { getParseErrorMessage } from 'vs/base/common/jsonErrorMessages';
|
||||
import { asDomUri } from 'vs/base/browser/dom';
|
||||
import { asCSSUrl } from 'vs/base/browser/dom';
|
||||
|
||||
export class FileIconThemeData implements IFileIconTheme {
|
||||
id: string;
|
||||
@@ -332,7 +332,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i
|
||||
let fonts = iconThemeDocument.fonts;
|
||||
if (Array.isArray(fonts)) {
|
||||
fonts.forEach(font => {
|
||||
let src = font.src.map(l => `url('${asDomUri(resolvePath(l.path))}') format('${l.format}')`).join(', ');
|
||||
let src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', ');
|
||||
cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; }`);
|
||||
});
|
||||
cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${fonts[0].size || '150%'}}`);
|
||||
@@ -343,7 +343,7 @@ function _processIconThemeDocument(id: string, iconThemeDocumentLocation: URI, i
|
||||
let definition = iconThemeDocument.iconDefinitions[defId];
|
||||
if (definition) {
|
||||
if (definition.iconPath) {
|
||||
cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: url("${asDomUri(resolvePath(definition.iconPath))}"); }`);
|
||||
cssRules.push(`${selectors.join(', ')} { content: ' '; background-image: ${asCSSUrl(resolvePath(definition.iconPath))}; }`);
|
||||
}
|
||||
if (definition.fontCharacter || definition.fontColor) {
|
||||
let body = '';
|
||||
|
||||
Reference in New Issue
Block a user