Merge from vscode 5e80bf449c995aa32a59254c0ff845d37da11b70 (#9317)

This commit is contained in:
Anthony Dresser
2020-02-24 21:15:52 -08:00
committed by GitHub
parent 628fd8d74d
commit 4a9c47d3d6
93 changed files with 3109 additions and 813 deletions

View File

@@ -109,6 +109,8 @@ export interface IProductConfiguration {
readonly msftInternalDomains?: string[];
readonly linkProtectionTrustedDomains?: readonly string[];
readonly 'configurationSync.store'?: { url: string, authenticationProviderId: string };
}
export interface IExeBasedExtensionTip {

View File

@@ -12,7 +12,6 @@ import { URI } from 'vs/base/common/uri';
import { IDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
import { IWindowsMainService } from 'vs/platform/windows/electron-main/windows';
import { isWindows } from 'vs/base/common/platform';
import { coalesce } from 'vs/base/common/arrays';
import { disposableTimeout } from 'vs/base/common/async';
function uriFromRawUrl(url: string): URI | null {
@@ -23,6 +22,16 @@ function uriFromRawUrl(url: string): URI | null {
}
}
/**
* A listener for URLs that are opened from the OS and handled by VSCode.
* Depending on the platform, this works differently:
* - Windows: we use `app.setAsDefaultProtocolClient()` to register VSCode with the OS
* and additionally add the `open-url` command line argument to identify.
* - macOS: we rely on `app.on('open-url')` to be called by the OS
* - Linux: we have a special shortcut installed (`resources/linux/code-url-handler.desktop`)
* that calls VSCode with the `open-url` command line argument
* (https://github.com/microsoft/vscode/pull/56727)
*/
export class ElectronURLListener {
private uris: URI[] = [];
@@ -31,36 +40,34 @@ export class ElectronURLListener {
private disposables = new DisposableStore();
constructor(
initial: string | string[],
@IURLService private readonly urlService: IURLService,
@IWindowsMainService windowsMainService: IWindowsMainService,
@IEnvironmentService environmentService: IEnvironmentService
initialUrisToHandle: URI[],
private readonly urlService: IURLService,
windowsMainService: IWindowsMainService,
environmentService: IEnvironmentService
) {
const globalBuffer = ((<any>global).getOpenUrls() || []) as string[];
const rawBuffer = [
...(typeof initial === 'string' ? [initial] : initial),
...globalBuffer
];
this.uris = coalesce(rawBuffer.map(uriFromRawUrl));
// the initial set of URIs we need to handle once the window is ready
this.uris = initialUrisToHandle;
// Windows: install as protocol handler
if (isWindows) {
const windowsParameters = environmentService.isBuilt ? [] : [`"${environmentService.appRoot}"`];
windowsParameters.push('--open-url', '--');
app.setAsDefaultProtocolClient(product.urlProtocol, process.execPath, windowsParameters);
}
// macOS: listen to `open-url` events from here on to handle
const onOpenElectronUrl = Event.map(
Event.fromNodeEventEmitter(app, 'open-url', (event: ElectronEvent, url: string) => ({ event, url })),
({ event, url }) => {
// always prevent default and return the url as string
event.preventDefault();
event.preventDefault(); // always prevent default and return the url as string
return url;
});
const onOpenUrl = Event.filter<URI | null, URI>(Event.map(onOpenElectronUrl, uriFromRawUrl), (uri): uri is URI => !!uri);
onOpenUrl(this.urlService.open, this.urlService, this.disposables);
// Send initial links to the window once it has loaded
const isWindowReady = windowsMainService.getWindows()
.filter(w => w.isReady)
.length > 0;

View File

@@ -20,6 +20,7 @@ import { FormattingOptions } from 'vs/base/common/jsonFormatter';
import { URI } from 'vs/base/common/uri';
import { isEqual, joinPath } from 'vs/base/common/resources';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IProductService } from 'vs/platform/product/common/productService';
export const CONFIGURATION_SYNC_STORE_KEY = 'configurationSync.store';
@@ -87,6 +88,7 @@ export function registerConfiguration(): IDisposable {
description: localize('sync.keybindingsPerPlatform', "Synchronize keybindings per platform."),
default: true,
scope: ConfigurationScope.APPLICATION,
tags: ['sync']
},
'sync.ignoredExtensions': {
'type': 'array',
@@ -95,7 +97,8 @@ export function registerConfiguration(): IDisposable {
'default': [],
'scope': ConfigurationScope.APPLICATION,
uniqueItems: true,
disallowSyncIgnore: true
disallowSyncIgnore: true,
tags: ['sync']
},
'sync.ignoredSettings': {
'type': 'array',
@@ -105,7 +108,8 @@ export function registerConfiguration(): IDisposable {
$ref: ignoredSettingsSchemaId,
additionalProperties: true,
uniqueItems: true,
disallowSyncIgnore: true
disallowSyncIgnore: true,
tags: ['sync']
}
}
});
@@ -140,8 +144,8 @@ export interface IUserDataSyncStore {
authenticationProviderId: string;
}
export function getUserDataSyncStore(configurationService: IConfigurationService): IUserDataSyncStore | undefined {
const value = configurationService.getValue<{ url: string, authenticationProviderId: string }>(CONFIGURATION_SYNC_STORE_KEY);
export function getUserDataSyncStore(productService: IProductService, configurationService: IConfigurationService): IUserDataSyncStore | undefined {
const value = productService[CONFIGURATION_SYNC_STORE_KEY] || configurationService.getValue<{ url: string, authenticationProviderId: string }>(CONFIGURATION_SYNC_STORE_KEY);
if (value && value.url && value.authenticationProviderId) {
return {
url: joinPath(URI.parse(value.url), 'v1'),

View File

@@ -11,6 +11,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IHeaders, IRequestOptions, IRequestContext } from 'vs/base/parts/request/common/request';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import { IProductService } from 'vs/platform/product/common/productService';
export class UserDataSyncStoreService extends Disposable implements IUserDataSyncStoreService {
@@ -19,13 +20,14 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn
readonly userDataSyncStore: IUserDataSyncStore | undefined;
constructor(
@IProductService productService: IProductService,
@IConfigurationService configurationService: IConfigurationService,
@IRequestService private readonly requestService: IRequestService,
@IAuthenticationTokenService private readonly authTokenService: IAuthenticationTokenService,
@IUserDataSyncLogService private readonly logService: IUserDataSyncLogService,
) {
super();
this.userDataSyncStore = getUserDataSyncStore(configurationService);
this.userDataSyncStore = getUserDataSyncStore(productService, configurationService);
}
async read(key: string, oldValue: IUserData | null, source?: SyncSource): Promise<IUserData> {

View File

@@ -34,6 +34,8 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { SettingsSynchroniser } from 'vs/platform/userDataSync/common/settingsSync';
import { Emitter } from 'vs/base/common/event';
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
export class UserDataSyncClient extends Disposable {
@@ -59,6 +61,8 @@ export class UserDataSyncClient extends Disposable {
const logService = new NullLogService();
this.instantiationService.stub(ILogService, logService);
this.instantiationService.stub(IProductService, { _serviceBrand: undefined, ...product });
const fileService = this._register(new FileService(logService));
fileService.registerProvider(Schemas.inMemory, new InMemoryFileSystemProvider());
this.instantiationService.stub(IFileService, fileService);