diff --git a/src/bootstrap-amd.js b/src/bootstrap-amd.js index 8b0ec252d25ba..752e4ab63ed67 100644 --- a/src/bootstrap-amd.js +++ b/src/bootstrap-amd.js @@ -14,7 +14,7 @@ const nlsConfig = bootstrap.setupNLS(); // Bootstrap: Loader loader.config({ - baseUrl: bootstrap.fileUriFromPath(__dirname, process.platform === 'win32'), + baseUrl: bootstrap.fileUriFromPath(__dirname, { isWindows: process.platform === 'win32' }), catchError: true, nodeRequire: require, nodeMain: __filename, diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index d3d05e5578f8d..40667ff6637e7 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -90,21 +90,17 @@ window.document.documentElement.setAttribute('lang', locale); - // do not advertise AMD to avoid confusing UMD modules loaded with nodejs - if (!sandbox) { - window['define'] = undefined; - } - // replace the patched electron fs with the original node fs for all AMD code (TODO@sandbox non-sandboxed only) if (!sandbox) { - require.define('fs', ['original-fs'], function (originalFS) { return originalFS; }); + require.define('fs', [], function () { return require.__$__nodeRequire('original-fs'); }); } window['MonacoEnvironment'] = {}; const loaderConfig = { - baseUrl: `${bootstrapLib.fileUriFromPath(configuration.appRoot, safeProcess.platform === 'win32')}/out`, - 'vs/nls': nlsConfig + baseUrl: `${bootstrapLib.fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`, + 'vs/nls': nlsConfig, + preferScriptTags: true }; // Enable loading of node modules: @@ -241,7 +237,7 @@ } /** - * @return {{ fileUriFromPath: (path: string, isWindows: boolean) => string; }} + * @return {{ fileUriFromPath: (path: string, config: { isWindows?: boolean, scheme?: string, fallbackAuthority?: string }) => string; }} */ function bootstrap() { // @ts-ignore (defined in bootstrap.js) diff --git a/src/bootstrap.js b/src/bootstrap.js index 58c6103d9be77..0cb6466aeafa7 100644 --- a/src/bootstrap.js +++ b/src/bootstrap.js @@ -88,10 +88,13 @@ /** * @param {string} path - * @param {boolean} isWindows + * @param {{ isWindows?: boolean, scheme?: string, fallbackAuthority?: string }} config * @returns {string} */ - function fileUriFromPath(path, isWindows) { + function fileUriFromPath(path, config) { + + // Since we are building a URI, we normalize any backlsash + // to slashes and we ensure that the path begins with a '/'. let pathName = path.replace(/\\/g, '/'); if (pathName.length > 0 && pathName.charAt(0) !== '/') { pathName = `/${pathName}`; @@ -99,10 +102,17 @@ /** @type {string} */ let uri; - if (isWindows && pathName.startsWith('//')) { // specially handle Windows UNC paths - uri = encodeURI(`file:${pathName}`); - } else { - uri = encodeURI(`file://${pathName}`); + + // Windows: in order to support UNC paths (which start with '//') + // that have their own authority, we do not use the provided authority + // but rather preserve it. + if (config.isWindows && pathName.startsWith('//')) { + uri = encodeURI(`${config.scheme || 'file'}:${pathName}`); + } + + // Otherwise we optionally add the provided authority if specified + else { + uri = encodeURI(`${config.scheme || 'file'}://${config.fallbackAuthority || ''}${pathName}`); } return uri.replace(/#/g, '%23'); diff --git a/src/main.js b/src/main.js index a901a747b92ef..bf42e0256846c 100644 --- a/src/main.js +++ b/src/main.js @@ -124,6 +124,15 @@ protocol.registerSchemesAsPrivileged([ corsEnabled: true, } }, + { + scheme: 'vscode-file', + privileges: { + secure: true, + standard: true, + supportFetchAPI: true, + corsEnabled: true + } + } ]); // Global app listeners diff --git a/src/vs/base/browser/dom.ts b/src/vs/base/browser/dom.ts index 8b381f96cc162..21d078305443c 100644 --- a/src/vs/base/browser/dom.ts +++ b/src/vs/base/browser/dom.ts @@ -13,7 +13,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; -import { Schemas, RemoteAuthorities } from 'vs/base/common/network'; +import { Schemas, FileAccess, RemoteAuthorities } from 'vs/base/common/network'; import { BrowserFeatures } from 'vs/base/browser/canIUse'; export function clearNode(node: HTMLElement): void { @@ -1223,10 +1223,12 @@ export function asDomUri(uri: URI): URI { if (!uri) { return uri; } - if (Schemas.vscodeRemote === uri.scheme) { + + if (uri.scheme === Schemas.vscodeRemote) { return RemoteAuthorities.rewrite(uri); } - return uri; + + return FileAccess.asBrowserUri(uri); } /** diff --git a/src/vs/base/common/amd.ts b/src/vs/base/common/amd.ts index ebea36794d0d7..d8ce68b55e249 100644 --- a/src/vs/base/common/amd.ts +++ b/src/vs/base/common/amd.ts @@ -5,10 +5,16 @@ import { URI } from 'vs/base/common/uri'; +/** + * @deprecated use `FileAccess.asFileUri(relativePath, requireFn).fsPath` + */ export function getPathFromAmdModule(requirefn: typeof require, relativePath: string): string { return getUriFromAmdModule(requirefn, relativePath).fsPath; } +/** + * @deprecated use `FileAccess.asFileUri()` for node.js contexts or `FileAccess.asBrowserUri` for browser contexts. + */ export function getUriFromAmdModule(requirefn: typeof require, relativePath: string): URI { return URI.parse(requirefn.toUrl(relativePath)); } diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index 4b6aebc16466d..08361e8b1ef2e 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -78,6 +78,12 @@ export namespace Schemas { * Scheme used for extension pages */ export const extension = 'extension'; + + /** + * Scheme used as a replacement of `file` scheme to load + * files with our custom protocol handler (desktop only). + */ + export const vscodeFileResource = 'vscode-file'; } class RemoteAuthoritiesImpl { @@ -129,3 +135,69 @@ class RemoteAuthoritiesImpl { } export const RemoteAuthorities = new RemoteAuthoritiesImpl(); + +class FileAccessImpl { + + private readonly FALLBACK_AUTHORITY = 'vscode-app'; + + /** + * Returns a URI to use in contexts where the browser is responsible + * for loading (e.g. fetch()) or when used within the DOM. + */ + asBrowserUri(uri: URI): URI; + asBrowserUri(moduleId: string, requireFn: typeof require): URI; + asBrowserUri(uriOrModule: URI | string, requireFn?: typeof require): URI { + const uri = this.toUri(uriOrModule, requireFn); + + // Only convert the URI if we are in a native context and it has `file:` scheme + if (platform.isNative && uri.scheme === Schemas.file) { + return uri.with({ + scheme: Schemas.vscodeFileResource, + // We need to provide an authority here so that it can serve + // as origin for network and loading matters in chromium. + // If the URI is not coming with an authority already, we + // add our own + authority: uri.authority || this.FALLBACK_AUTHORITY, + query: null, + fragment: null + }); + } + + return uri; + } + + /** + * Returns the `file` URI to use in contexts where node.js + * is responsible for loading. + */ + asFileUri(uri: URI): URI; + asFileUri(moduleId: string, requireFn: typeof require): URI; + asFileUri(uriOrModule: URI | string, requireFn?: typeof require): URI { + const uri = this.toUri(uriOrModule, requireFn); + + // Only convert the URI if it is not already `file:` scheme + if (uri.scheme !== Schemas.file) { + return uri.with({ + scheme: Schemas.file, + // Only preserve the `authority` if it is different from + // our fallback authority. This ensures we properly preserve + // Windows UNC paths that come with their own authority. + authority: uri.authority !== this.FALLBACK_AUTHORITY ? uri.authority : null, + query: null, + fragment: null + }); + } + + return uri; + } + + private toUri(uriOrModule: URI | string, requireFn?: typeof require): URI { + if (URI.isUri(uriOrModule)) { + return uriOrModule; + } + + return URI.parse(requireFn!.toUrl(uriOrModule)); + } +} + +export const FileAccess = new FileAccessImpl(); diff --git a/src/vs/base/node/paths.ts b/src/vs/base/node/paths.ts index 66930cdaf4bc6..977eaf8806fcc 100644 --- a/src/vs/base/node/paths.ts +++ b/src/vs/base/node/paths.ts @@ -3,14 +3,14 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; interface IPaths { getAppDataPath(platform: string): string; getDefaultUserDataPath(platform: string): string; } -const pathsPath = getPathFromAmdModule(require, 'paths'); +const pathsPath = FileAccess.asFileUri('paths', require).fsPath; const paths = require.__$__nodeRequire(pathsPath); export const getAppDataPath = paths.getAppDataPath; export const getDefaultUserDataPath = paths.getDefaultUserDataPath; diff --git a/src/vs/base/node/processes.ts b/src/vs/base/node/processes.ts index 6ccedd679edcb..302fa75997e75 100644 --- a/src/vs/base/node/processes.ts +++ b/src/vs/base/node/processes.ts @@ -15,7 +15,7 @@ import * as extpath from 'vs/base/common/extpath'; import * as Platform from 'vs/base/common/platform'; import { LineDecoder } from 'vs/base/node/decoder'; import { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode, Executable } from 'vs/base/common/processes'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export { CommandOptions, ForkOptions, SuccessData, Source, TerminateResponse, TerminateResponseCode }; export type ValueCallback = (value: T | Promise) => void; @@ -67,7 +67,7 @@ function terminateProcess(process: cp.ChildProcess, cwd?: string): Promise { cp.execFile(cmd, [process.pid.toString()], { encoding: 'utf8', shell: true } as cp.ExecFileOptions, (err, stdout, stderr) => { if (err) { diff --git a/src/vs/base/node/ps.ts b/src/vs/base/node/ps.ts index 31223d4a5d81c..dd5d53d67b4da 100644 --- a/src/vs/base/node/ps.ts +++ b/src/vs/base/node/ps.ts @@ -5,7 +5,7 @@ import { exec } from 'child_process'; import { ProcessItem } from 'vs/base/common/processes'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export function listProcesses(rootPid: number): Promise { @@ -180,7 +180,7 @@ export function listProcesses(rootPid: number): Promise { // The cpu usage value reported on Linux is the average over the process lifetime, // recalculate the usage over a one second interval // JSON.stringify is needed to escape spaces, https://github.com/nodejs/node/issues/6803 - let cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/cpuUsage.sh')); + let cmd = JSON.stringify(FileAccess.asFileUri('vs/base/node/cpuUsage.sh', require).fsPath); cmd += ' ' + pids.join(' '); exec(cmd, {}, (err, stdout, stderr) => { @@ -208,7 +208,7 @@ export function listProcesses(rootPid: number): Promise { if (process.platform !== 'linux') { reject(err || new Error(stderr.toString())); } else { - const cmd = JSON.stringify(getPathFromAmdModule(require, 'vs/base/node/ps.sh')); + const cmd = JSON.stringify(FileAccess.asFileUri('vs/base/node/ps.sh', require).fsPath); exec(cmd, {}, (err, stdout, stderr) => { if (err || stderr) { reject(err || new Error(stderr.toString())); diff --git a/src/vs/base/test/browser/dom.test.ts b/src/vs/base/test/browser/dom.test.ts index f5c8e65dac66b..3aff432e1456b 100644 --- a/src/vs/base/test/browser/dom.test.ts +++ b/src/vs/base/test/browser/dom.test.ts @@ -5,6 +5,9 @@ import * as assert from 'assert'; import * as dom from 'vs/base/browser/dom'; +import { Schemas } from 'vs/base/common/network'; +import { isNative } from 'vs/base/common/platform'; +import { URI } from 'vs/base/common/uri'; const $ = dom.$; suite('dom', () => { @@ -135,4 +138,16 @@ suite('dom', () => { assert.equal(firstChild.textContent, 'foobar'); }); }); + + test('asDomUri', function () { + const fileUri = URI.file('something'); + + const domUri = dom.asDomUri(fileUri); + + if (isNative) { + assert.equal(domUri.scheme, Schemas.vscodeFileResource); + } else { + assert.equal(domUri.scheme, fileUri.scheme); + } + }); }); diff --git a/src/vs/base/test/common/network.test.ts b/src/vs/base/test/common/network.test.ts new file mode 100644 index 0000000000000..423797ae8b81f --- /dev/null +++ b/src/vs/base/test/common/network.test.ts @@ -0,0 +1,63 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as assert from 'assert'; +import { URI } from 'vs/base/common/uri'; +import { FileAccess, Schemas } from 'vs/base/common/network'; +import { isEqual } from 'vs/base/common/resources'; +import { isWeb } from 'vs/base/common/platform'; + +suite('network', () => { + + (isWeb ? test.skip : test)('FileAccess: URI (native)', () => { + + // asCodeUri() & asFileUri(): simple, without authority + let originalFileUri = URI.file('network.test.ts'); + let browserUri = FileAccess.asBrowserUri(originalFileUri); + assert.ok(browserUri.authority.length > 0); + let fileUri = FileAccess.asFileUri(browserUri); + assert.equal(fileUri.authority.length, 0); + assert(isEqual(originalFileUri, fileUri)); + + // asCodeUri() & asFileUri(): with authority + originalFileUri = URI.file('network.test.ts').with({ authority: 'test-authority' }); + browserUri = FileAccess.asBrowserUri(originalFileUri); + assert.equal(browserUri.authority, originalFileUri.authority); + fileUri = FileAccess.asFileUri(browserUri); + assert(isEqual(originalFileUri, fileUri)); + }); + + (isWeb ? test.skip : test)('FileAccess: moduleId (native)', () => { + const browserUri = FileAccess.asBrowserUri('vs/base/test/node/network.test', require); + assert.equal(browserUri.scheme, Schemas.vscodeFileResource); + + const fileUri = FileAccess.asFileUri('vs/base/test/node/network.test', require); + assert.equal(fileUri.scheme, Schemas.file); + }); + + (isWeb ? test.skip : test)('FileAccess: query and fragment is dropped (native)', () => { + let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); + let browserUri = FileAccess.asBrowserUri(originalFileUri); + assert.equal(browserUri.query, ''); + assert.equal(browserUri.fragment, ''); + }); + + (isWeb ? test.skip : test)('FileAccess: query and fragment is kept if URI is already of same scheme (native)', () => { + let originalFileUri = URI.file('network.test.ts').with({ query: 'foo=bar', fragment: 'something' }); + let browserUri = FileAccess.asBrowserUri(originalFileUri.with({ scheme: Schemas.vscodeFileResource })); + assert.equal(browserUri.query, 'foo=bar'); + assert.equal(browserUri.fragment, 'something'); + + let fileUri = FileAccess.asFileUri(originalFileUri); + assert.equal(fileUri.query, 'foo=bar'); + assert.equal(fileUri.fragment, 'something'); + }); + + (isWeb ? test.skip : test)('FileAccess: web', () => { + const originalHttpsUri = URI.file('network.test.ts').with({ scheme: 'https' }); + const browserUri = FileAccess.asBrowserUri(originalHttpsUri); + assert.equal(originalHttpsUri.toString(), browserUri.toString()); + }); +}); diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 256f6119e5f05..b46d11c890547 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -34,6 +34,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper import { getDelayedChannel, StaticRouter, createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/common/ipc'; import product from 'vs/platform/product/common/product'; import { ProxyAuthHandler } from 'vs/code/electron-main/auth'; +import { FileProtocolHandler } from 'vs/code/electron-main/protocol'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows'; import { ActiveWindowManager } from 'vs/platform/windows/electron-main/windowTracker'; @@ -349,6 +350,9 @@ export class CodeApplication extends Disposable { this.logService.error(error); } + // Setup Protocol Handler + this._register(new FileProtocolHandler(this.environmentService, this.logService)); + // Create Electron IPC Server const electronIpcServer = new ElectronIPCServer(); diff --git a/src/vs/code/electron-main/auth.ts b/src/vs/code/electron-main/auth.ts index f57aef11f3e4e..b4096018623f7 100644 --- a/src/vs/code/electron-main/auth.ts +++ b/src/vs/code/electron-main/auth.ts @@ -6,8 +6,8 @@ import { localize } from 'vs/nls'; import { Disposable } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; +import { FileAccess } from 'vs/base/common/network'; import { BrowserWindow, BrowserWindowConstructorOptions, app, AuthInfo, WebContents, Event as ElectronEvent } from 'electron'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; type LoginEvent = { event: ElectronEvent; @@ -59,7 +59,7 @@ export class ProxyAuthHandler extends Disposable { show: true, title: 'VS Code', webPreferences: { - preload: getPathFromAmdModule(require, 'vs/base/parts/sandbox/electron-browser/preload.js'), + preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, sandbox: true, contextIsolation: true, enableWebSQL: false, @@ -76,7 +76,7 @@ export class ProxyAuthHandler extends Disposable { } const win = new BrowserWindow(opts); - const url = require.toUrl('vs/code/electron-sandbox/proxy/auth.html'); + const windowUrl = FileAccess.asBrowserUri('vs/code/electron-sandbox/proxy/auth.html', require); const proxyUrl = `${authInfo.host}:${authInfo.port}`; const title = localize('authRequire', "Proxy Authentication Required"); const message = localize('proxyauth', "The proxy {0} requires authentication.", proxyUrl); @@ -97,6 +97,6 @@ export class ProxyAuthHandler extends Disposable { win.close(); } }); - win.loadURL(url); + win.loadURL(windowUrl.toString(true)); } } diff --git a/src/vs/code/electron-main/protocol.ts b/src/vs/code/electron-main/protocol.ts new file mode 100644 index 0000000000000..5f792b618b7d4 --- /dev/null +++ b/src/vs/code/electron-main/protocol.ts @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { Disposable, toDisposable } from 'vs/base/common/lifecycle'; +import { FileAccess, Schemas } from 'vs/base/common/network'; +import { URI } from 'vs/base/common/uri'; +import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; +import { session } from 'electron'; +import { ILogService } from 'vs/platform/log/common/log'; +import { coalesce } from 'vs/base/common/arrays'; +import { extUriBiasedIgnorePathCase } from 'vs/base/common/resources'; + +type ProtocolCallback = { (result: string | Electron.FilePathWithHeaders | { error: number }): void }; + +export class FileProtocolHandler extends Disposable { + + constructor( + environmentService: INativeEnvironmentService, + private readonly logService: ILogService + ) { + super(); + + const { defaultSession } = session; + + // Define a set of roots we allow loading from + const validRoots = coalesce([ + URI.file(environmentService.appRoot), + environmentService.extensionsPath ? URI.file(environmentService.extensionsPath) : undefined, + ...environmentService.extensionDevelopmentLocationURI ?? [] + ]); + + // Register vscode-file:// handler + defaultSession.protocol.registerFileProtocol(Schemas.vscodeFileResource, (request, callback) => this.handleResourceRequest(request, validRoots, callback as unknown as ProtocolCallback)); + + // Block any file:// access + defaultSession.protocol.interceptFileProtocol(Schemas.file, (request, callback) => this.handleFileRequest(request, callback as unknown as ProtocolCallback)); + + // Cleanup + this._register(toDisposable(() => { + defaultSession.protocol.unregisterProtocol(Schemas.vscodeFileResource); + defaultSession.protocol.uninterceptProtocol(Schemas.file); + })); + } + + private async handleFileRequest(request: Electron.Request, callback: ProtocolCallback) { + const uri = URI.parse(request.url); + + this.logService.error(`Refused to load resource ${uri.fsPath} from ${Schemas.file}: protocol`); + callback({ error: -3 /* ABORTED */ }); + } + + private async handleResourceRequest(request: Electron.Request, validRoots: URI[], callback: ProtocolCallback) { + const uri = URI.parse(request.url); + + // Restore the `vscode-file` URI to a `file` URI so that we can + // ensure the root is valid and properly tell Chrome where the + // resource is at. + const fileUri = FileAccess.asFileUri(uri); + if (validRoots.some(validRoot => extUriBiasedIgnorePathCase.isEqualOrParent(fileUri, validRoot))) { + return callback({ + path: fileUri.fsPath + }); + } + + this.logService.error(`${Schemas.vscodeFileResource}: Refused to load resource ${fileUri.fsPath}}`); + callback({ error: -3 /* ABORTED */ }); + } +} diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/electron-main/sharedProcess.ts index a40e860b384d5..661c653632dac 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/electron-main/sharedProcess.ts @@ -13,7 +13,7 @@ import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifec import { IThemeMainService } from 'vs/platform/theme/electron-main/themeMainService'; import { toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Event } from 'vs/base/common/event'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export class SharedProcess implements ISharedProcess { @@ -41,7 +41,8 @@ export class SharedProcess implements ISharedProcess { show: false, backgroundColor: this.themeMainService.getBackgroundColor(), webPreferences: { - preload: getPathFromAmdModule(require, 'vs/base/parts/sandbox/electron-browser/preload.js'), + preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, + v8CacheOptions: this.environmentService.v8CacheOptions, nodeIntegration: true, enableWebSQL: false, enableRemoteModule: false, @@ -60,8 +61,10 @@ export class SharedProcess implements ISharedProcess { windowId: this.window.id }; - const url = `${require.toUrl('vs/code/electron-browser/sharedProcess/sharedProcess.html')}?config=${encodeURIComponent(JSON.stringify(config))}`; - this.window.loadURL(url); + const windowUrl = FileAccess + .asBrowserUri('vs/code/electron-browser/sharedProcess/sharedProcess.html', require) + .with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` }); + this.window.loadURL(windowUrl.toString(true)); // Prevent the window from dying const onClose = (e: ElectronEvent) => { diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index 17dcfd5a97b0c..4d08fde5aa39e 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -34,9 +34,8 @@ import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService'; import { IStorageMainService } from 'vs/platform/storage/node/storageMainService'; import { IFileService } from 'vs/platform/files/common/files'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { ColorScheme } from 'vs/platform/theme/common/theme'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; -import { Schemas } from 'vs/base/common/network'; export interface IWindowCreationOptions { state: IWindowState; @@ -168,7 +167,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { show: !isFullscreenOrMaximized, title: product.nameLong, webPreferences: { - preload: getPathFromAmdModule(require, 'vs/base/parts/sandbox/electron-browser/preload.js'), + preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, + v8CacheOptions: this.environmentService.v8CacheOptions, enableWebSQL: false, enableRemoteModule: false, spellcheck: false, @@ -190,6 +190,8 @@ export class CodeWindow extends Disposable implements ICodeWindow { } }; + this.logService.trace(`window#ctor: using V8 cache options: ${this.environmentService.v8CacheOptions}`); + // Apply icon to window // Linux: always // Windows: only when running out of sources, otherwise an icon is set by us on the executable @@ -837,7 +839,10 @@ export class CodeWindow extends Disposable implements ICodeWindow { workbench = 'vs/code/electron-browser/workbench/workbench.html'; } - return `${require.toUrl(workbench)}?config=${encodeURIComponent(JSON.stringify(config))}`; + return FileAccess + .asBrowserUri(workbench, require) + .with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` }) + .toString(true); } serializeWindowState(): IWindowState { diff --git a/src/vs/editor/test/browser/services/decorationRenderOptions.test.ts b/src/vs/editor/test/browser/services/decorationRenderOptions.test.ts index bc52241697685..9c8c6c6ed64ff 100644 --- a/src/vs/editor/test/browser/services/decorationRenderOptions.test.ts +++ b/src/vs/editor/test/browser/services/decorationRenderOptions.test.ts @@ -149,25 +149,33 @@ suite('Decoration Render Options', () => { assert(readStyleSheet(styleSheet).indexOf(`{background:url('data:image/svg+xml;base64,PHN2ZyB4b+') center center no-repeat;}`) > 0); s.removeDecorationType('example'); + function assertBackground(url1: string, url2: string) { + const actual = readStyleSheet(styleSheet); + assert( + actual.indexOf(`{background:url('${url1}') center center no-repeat;}`) > 0 + || actual.indexOf(`{background:url('${url2}') center center no-repeat;}`) > 0 + ); + } + if (platform.isWindows) { // windows file path (used as string) s.registerDecorationType('example', { gutterIconPath: URI.file('c:\\files\\miles\\more.png') }); - assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///c:/files/miles/more.png') center center no-repeat;}`) > 0); + assertBackground('file:///c:/files/miles/more.png', 'vscode-file://vscode-app/c:/files/miles/more.png'); s.removeDecorationType('example'); // single quote must always be escaped/encoded s.registerDecorationType('example', { gutterIconPath: URI.file('c:\\files\\foo\\b\'ar.png') }); - assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///c:/files/foo/b%27ar.png') center center no-repeat;}`) > 0); + assertBackground('file:///c:/files/foo/b%27ar.png', 'vscode-file://vscode-app/c:/files/foo/b%27ar.png'); s.removeDecorationType('example'); } else { // unix file path (used as string) s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/bar.png') }); - assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///Users/foo/bar.png') center center no-repeat;}`) > 0); + assertBackground('file:///Users/foo/bar.png', 'vscode-file://vscode-app/Users/foo/bar.png'); s.removeDecorationType('example'); // single quote must always be escaped/encoded s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/b\'ar.png') }); - assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///Users/foo/b%27ar.png') center center no-repeat;}`) > 0); + assertBackground('file:///Users/foo/b%27ar.png', 'vscode-file://vscode-app/Users/foo/b%27ar.png'); s.removeDecorationType('example'); } diff --git a/src/vs/platform/environment/common/argv.ts b/src/vs/platform/environment/common/argv.ts index db19acb10c785..aeb79aa99d11b 100644 --- a/src/vs/platform/environment/common/argv.ts +++ b/src/vs/platform/environment/common/argv.ts @@ -77,6 +77,7 @@ export interface NativeParsedArgs { 'force-user-env'?: boolean; 'sync'?: 'on' | 'off'; '__sandbox'?: boolean; + '__v8-cache-options'?: string; // chromium command line args: https://electronjs.org/docs/all#supported-chrome-command-line-switches 'no-proxy-server'?: boolean; diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index eebf675762d57..17060f62e4f9a 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -119,6 +119,7 @@ export interface INativeEnvironmentService extends IEnvironmentService { // --- Misc. config disableUpdates: boolean; sandbox: boolean; + v8CacheOptions: 'none' | 'code' | 'bypassHeatCheck' | 'bypassHeatCheckAndEagerCompile'; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // NOTE: KEEP THIS INTERFACE AS SMALL AS POSSIBLE. AS SUCH: diff --git a/src/vs/platform/environment/node/argv.ts b/src/vs/platform/environment/node/argv.ts index fba8ce9fa295d..281613c2a8d19 100644 --- a/src/vs/platform/environment/node/argv.ts +++ b/src/vs/platform/environment/node/argv.ts @@ -111,6 +111,7 @@ export const OPTIONS: OptionDescriptions> = { 'force-user-env': { type: 'boolean' }, 'open-devtools': { type: 'boolean' }, '__sandbox': { type: 'boolean' }, + '__v8-cache-options': { type: 'string' }, // chromium flags 'no-proxy-server': { type: 'boolean' }, diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 5f039341a18d9..e546994fcc77a 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -14,7 +14,7 @@ import { memoize } from 'vs/base/common/decorators'; import product from 'vs/platform/product/common/product'; import { toLocalISOString } from 'vs/base/common/date'; import { isWindows, Platform, platform } from 'vs/base/common/platform'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; export class NativeEnvironmentService implements INativeEnvironmentService { @@ -24,7 +24,7 @@ export class NativeEnvironmentService implements INativeEnvironmentService { get args(): NativeParsedArgs { return this._args; } @memoize - get appRoot(): string { return path.dirname(getPathFromAmdModule(require, '')); } + get appRoot(): string { return path.dirname(FileAccess.asFileUri('', require).fsPath); } readonly logsPath: string; @@ -111,7 +111,7 @@ export class NativeEnvironmentService implements INativeEnvironmentService { if (fromArgs) { return fromArgs; } else { - return path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); + return path.normalize(path.join(FileAccess.asFileUri('', require).fsPath, '..', 'extensions')); } } @@ -217,6 +217,16 @@ export class NativeEnvironmentService implements INativeEnvironmentService { get sandbox(): boolean { return !!this._args['__sandbox']; } + @memoize + get v8CacheOptions(): 'none' | 'code' | 'bypassHeatCheck' | 'bypassHeatCheckAndEagerCompile' { + const commandLineArg = this._args['__v8-cache-options']; + if (commandLineArg === 'none' || commandLineArg === 'code' || commandLineArg === 'bypassHeatCheck' || commandLineArg === 'bypassHeatCheckAndEagerCompile') { + return commandLineArg; + } + + return 'bypassHeatCheck'; + } + constructor(private _args: NativeParsedArgs) { if (!process.env['VSCODE_LOGS']) { const key = toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, ''); diff --git a/src/vs/platform/extensionManagement/common/extensionManagement.ts b/src/vs/platform/extensionManagement/common/extensionManagement.ts index fa4e7350910f9..7e30f75eea86c 100644 --- a/src/vs/platform/extensionManagement/common/extensionManagement.ts +++ b/src/vs/platform/extensionManagement/common/extensionManagement.ts @@ -10,6 +10,7 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation' import { URI } from 'vs/base/common/uri'; import { CancellationToken } from 'vs/base/common/cancellation'; import { IExtensionManifest, IExtension, ExtensionType } from 'vs/platform/extensions/common/extensions'; +import { FileAccess } from 'vs/base/common/network'; export const EXTENSION_IDENTIFIER_PATTERN = '^([a-z0-9A-Z][a-z0-9-A-Z]*)\\.([a-z0-9A-Z][a-z0-9-A-Z]*)$'; export const EXTENSION_IDENTIFIER_REGEX = new RegExp(EXTENSION_IDENTIFIER_PATTERN); @@ -260,7 +261,7 @@ export interface IExtensionTipsService { } -export const DefaultIconPath = require.toUrl('./media/defaultIcon.png'); +export const DefaultIconPath = FileAccess.asBrowserUri('./media/defaultIcon.png', require).toString(true); export const ExtensionsLabel = localize('extensions', "Extensions"); export const ExtensionsLocalizedLabel = { value: ExtensionsLabel, original: 'Extensions' }; export const ExtensionsChannelId = 'extensions'; diff --git a/src/vs/platform/extensionManagement/node/extensionsScanner.ts b/src/vs/platform/extensionManagement/node/extensionsScanner.ts index a2c840c049b06..e7342348d46cb 100644 --- a/src/vs/platform/extensionManagement/node/extensionsScanner.ts +++ b/src/vs/platform/extensionManagement/node/extensionsScanner.ts @@ -14,7 +14,6 @@ import { areSameExtensions, ExtensionIdentifierWithVersion, groupByExtension, ge import { Limiter, Queue } from 'vs/base/common/async'; import { URI } from 'vs/base/common/uri'; import { INativeEnvironmentService } from 'vs/platform/environment/common/environment'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { localizeManifest } from 'vs/platform/extensionManagement/common/extensionNls'; import { localize } from 'vs/nls'; import { IProductService } from 'vs/platform/product/common/productService'; @@ -23,6 +22,7 @@ import { extract, ExtractError } from 'vs/base/node/zip'; import { isWindows } from 'vs/base/common/platform'; import { flatten } from 'vs/base/common/arrays'; import { IStringDictionary } from 'vs/base/common/collections'; +import { FileAccess } from 'vs/base/common/network'; const ERROR_SCANNING_SYS_EXTENSIONS = 'scanningSystem'; const ERROR_SCANNING_USER_EXTENSIONS = 'scanningUser'; @@ -336,7 +336,7 @@ export class ExtensionsScanner extends Disposable { private _devSystemExtensionsPath: string | null = null; private get devSystemExtensionsPath(): string { if (!this._devSystemExtensionsPath) { - this._devSystemExtensionsPath = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', '.build', 'builtInExtensions')); + this._devSystemExtensionsPath = path.normalize(path.join(FileAccess.asFileUri('', require).fsPath, '..', '.build', 'builtInExtensions')); } return this._devSystemExtensionsPath; } diff --git a/src/vs/platform/files/node/watcher/nsfw/watcherService.ts b/src/vs/platform/files/node/watcher/nsfw/watcherService.ts index 36cc3c569955f..79fa3ba25f6c4 100644 --- a/src/vs/platform/files/node/watcher/nsfw/watcherService.ts +++ b/src/vs/platform/files/node/watcher/nsfw/watcherService.ts @@ -8,7 +8,7 @@ import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { IDiskFileChange, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWatcherRequest, IWatcherService } from 'vs/platform/files/node/watcher/nsfw/watcher'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export class FileWatcher extends Disposable { @@ -34,7 +34,7 @@ export class FileWatcher extends Disposable { private startWatching(): void { const client = this._register(new Client( - getPathFromAmdModule(require, 'bootstrap-fork'), + FileAccess.asFileUri('bootstrap-fork', require).fsPath, { serverName: 'File Watcher (nsfw)', args: ['--type=watcherService'], diff --git a/src/vs/platform/files/node/watcher/unix/watcherService.ts b/src/vs/platform/files/node/watcher/unix/watcherService.ts index 18da926b0ef79..e561cc8e51375 100644 --- a/src/vs/platform/files/node/watcher/unix/watcherService.ts +++ b/src/vs/platform/files/node/watcher/unix/watcherService.ts @@ -8,7 +8,7 @@ import { Client } from 'vs/base/parts/ipc/node/ipc.cp'; import { IDiskFileChange, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; import { Disposable } from 'vs/base/common/lifecycle'; import { IWatcherRequest, IWatcherOptions, IWatcherService } from 'vs/platform/files/node/watcher/unix/watcher'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export class FileWatcher extends Disposable { @@ -35,7 +35,7 @@ export class FileWatcher extends Disposable { private startWatching(): void { const client = this._register(new Client( - getPathFromAmdModule(require, 'bootstrap-fork'), + FileAccess.asFileUri('bootstrap-fork', require).fsPath, { serverName: 'File Watcher (chokidar)', args: ['--type=watcherService'], diff --git a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts index 9eda54b3c902d..4a13ec02886eb 100644 --- a/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts +++ b/src/vs/platform/files/node/watcher/win32/csharpWatcherService.ts @@ -8,7 +8,7 @@ import { FileChangeType } from 'vs/platform/files/common/files'; import * as decoder from 'vs/base/node/decoder'; import * as glob from 'vs/base/common/glob'; import { IDiskFileChange, ILogMessage } from 'vs/platform/files/node/watcher/watcher'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; export class OutOfProcessWin32FolderWatcher { @@ -50,7 +50,7 @@ export class OutOfProcessWin32FolderWatcher { args.push('-verbose'); } - this.handle = cp.spawn(getPathFromAmdModule(require, 'vs/platform/files/node/watcher/win32/CodeHelper.exe'), args); + this.handle = cp.spawn(FileAccess.asFileUri('vs/platform/files/node/watcher/win32/CodeHelper.exe', require).fsPath, args); const stdoutLineDecoder = new decoder.LineDecoder(); diff --git a/src/vs/platform/issue/electron-main/issueMainService.ts b/src/vs/platform/issue/electron-main/issueMainService.ts index ee27d4c8e3895..a01f4b1cb8eb9 100644 --- a/src/vs/platform/issue/electron-main/issueMainService.ts +++ b/src/vs/platform/issue/electron-main/issueMainService.ts @@ -18,9 +18,9 @@ import { ILogService } from 'vs/platform/log/common/log'; import { IWindowState } from 'vs/platform/windows/electron-main/windows'; import { listProcesses } from 'vs/base/node/ps'; import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { zoomLevelToZoomFactor } from 'vs/platform/windows/common/windows'; +import { FileAccess } from 'vs/base/common/network'; const DEFAULT_BACKGROUND_COLOR = '#1E1E1E'; @@ -195,7 +195,8 @@ export class IssueMainService implements ICommonIssueService { title: localize('issueReporter', "Issue Reporter"), backgroundColor: data.styles.backgroundColor || DEFAULT_BACKGROUND_COLOR, webPreferences: { - preload: getPathFromAmdModule(require, 'vs/base/parts/sandbox/electron-browser/preload.js'), + preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, + v8CacheOptions: this.environmentService.v8CacheOptions, enableWebSQL: false, enableRemoteModule: false, spellcheck: false, @@ -261,7 +262,8 @@ export class IssueMainService implements ICommonIssueService { backgroundColor: data.styles.backgroundColor, title: localize('processExplorer', "Process Explorer"), webPreferences: { - preload: getPathFromAmdModule(require, 'vs/base/parts/sandbox/electron-browser/preload.js'), + preload: FileAccess.asFileUri('vs/base/parts/sandbox/electron-browser/preload.js', require).fsPath, + v8CacheOptions: this.environmentService.v8CacheOptions, enableWebSQL: false, enableRemoteModule: false, spellcheck: false, @@ -294,7 +296,7 @@ export class IssueMainService implements ICommonIssueService { }; this._processExplorerWindow.loadURL( - toLauchUrl('vs/code/electron-sandbox/processExplorer/processExplorer.html', windowConfiguration)); + toWindowUrl('vs/code/electron-sandbox/processExplorer/processExplorer.html', windowConfiguration)); this._processExplorerWindow.on('close', () => this._processExplorerWindow = null); @@ -435,11 +437,11 @@ export class IssueMainService implements ICommonIssueService { } }; - return toLauchUrl('vs/code/electron-sandbox/issue/issueReporter.html', windowConfiguration); + return toWindowUrl('vs/code/electron-sandbox/issue/issueReporter.html', windowConfiguration); } } -function toLauchUrl(pathToHtml: string, windowConfiguration: T): string { +function toWindowUrl(modulePathToHtml: string, windowConfiguration: T): string { const environment = parseArgs(process.argv, OPTIONS); const config = Object.assign(environment, windowConfiguration); for (const keyValue of Object.keys(config)) { @@ -449,5 +451,8 @@ function toLauchUrl(pathToHtml: string, windowConfiguration: T): string { } } - return `${require.toUrl(pathToHtml)}?config=${encodeURIComponent(JSON.stringify(config))}`; + return FileAccess + .asBrowserUri(modulePathToHtml, require) + .with({ query: `config=${encodeURIComponent(JSON.stringify(config))}` }) + .toString(true); } diff --git a/src/vs/platform/product/common/product.ts b/src/vs/platform/product/common/product.ts index 55567d4b537c0..798faa74ae825 100644 --- a/src/vs/platform/product/common/product.ts +++ b/src/vs/platform/product/common/product.ts @@ -5,9 +5,9 @@ import { IProductConfiguration } from 'vs/platform/product/common/productService'; import { isWeb } from 'vs/base/common/platform'; -import * as path from 'vs/base/common/path'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { env } from 'vs/base/common/process'; +import { FileAccess } from 'vs/base/common/network'; +import { dirname, joinPath } from 'vs/base/common/resources'; let product: IProductConfiguration; @@ -43,10 +43,10 @@ if (isWeb || typeof require === 'undefined' || typeof require.__$__nodeRequire ! else { // Obtain values from product.json and package.json - const rootPath = path.dirname(getPathFromAmdModule(require, '')); + const rootPath = dirname(FileAccess.asFileUri('', require)); - product = require.__$__nodeRequire(path.join(rootPath, 'product.json')); - const pkg = require.__$__nodeRequire(path.join(rootPath, 'package.json')) as { version: string; }; + product = require.__$__nodeRequire(joinPath(rootPath, 'product.json').fsPath); + const pkg = require.__$__nodeRequire(joinPath(rootPath, 'package.json').fsPath) as { version: string; }; // Running out of sources if (env['VSCODE_DEV']) { diff --git a/src/vs/workbench/browser/parts/editor/editor.contribution.ts b/src/vs/workbench/browser/parts/editor/editor.contribution.ts index a6a52a00e5a17..f8accd9a98343 100644 --- a/src/vs/workbench/browser/parts/editor/editor.contribution.ts +++ b/src/vs/workbench/browser/parts/editor/editor.contribution.ts @@ -54,7 +54,7 @@ import { PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry'; import { IQuickAccessRegistry, Extensions as QuickAccessExtensions } from 'vs/platform/quickinput/common/quickAccess'; import { ActiveGroupEditorsByMostRecentlyUsedQuickAccess, AllEditorsByAppearanceQuickAccess, AllEditorsByMostRecentlyUsedQuickAccess } from 'vs/workbench/browser/parts/editor/editorQuickAccess'; import { IPathService } from 'vs/workbench/services/path/common/pathService'; -import { getUriFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; // Register String Editor Registry.as(EditorExtensions.Editors).registerEditor( @@ -423,13 +423,13 @@ editorCommands.setup(); // Touch Bar if (isMacintosh) { MenuRegistry.appendMenuItem(MenuId.TouchBarContext, { - command: { id: NavigateBackwardsAction.ID, title: NavigateBackwardsAction.LABEL, icon: { dark: getUriFromAmdModule(require, 'vs/workbench/browser/parts/editor/media/back-tb.png') } }, + command: { id: NavigateBackwardsAction.ID, title: NavigateBackwardsAction.LABEL, icon: { dark: FileAccess.asFileUri('vs/workbench/browser/parts/editor/media/back-tb.png', require) } }, group: 'navigation', order: 0 }); MenuRegistry.appendMenuItem(MenuId.TouchBarContext, { - command: { id: NavigateForwardAction.ID, title: NavigateForwardAction.LABEL, icon: { dark: getUriFromAmdModule(require, 'vs/workbench/browser/parts/editor/media/forward-tb.png') } }, + command: { id: NavigateForwardAction.ID, title: NavigateForwardAction.LABEL, icon: { dark: FileAccess.asFileUri('vs/workbench/browser/parts/editor/media/forward-tb.png', require) } }, group: 'navigation', order: 1 }); diff --git a/src/vs/workbench/browser/parts/editor/editorGroupView.ts b/src/vs/workbench/browser/parts/editor/editorGroupView.ts index 4f209f32f0a8a..9f5c4d3ee01fe 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupView.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupView.ts @@ -46,13 +46,12 @@ import { withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types'; import { hash } from 'vs/base/common/hash'; import { guessMimeTypes } from 'vs/base/common/mime'; import { extname } from 'vs/base/common/resources'; -import { Schemas } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { EditorActivation, EditorOpenContext } from 'vs/platform/editor/common/editor'; import { IDialogService, IFileDialogService, ConfirmResult } from 'vs/platform/dialogs/common/dialogs'; import { ILogService } from 'vs/platform/log/common/log'; import { Codicon } from 'vs/base/common/codicons'; import { IFilesConfigurationService, AutoSaveMode } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; export class EditorGroupView extends Themable implements IEditorGroupView { @@ -1781,7 +1780,7 @@ registerThemingParticipant((theme, collector, environment) => { const letterpress = `./media/letterpress${theme.type === 'dark' ? '-dark' : theme.type === 'hc' ? '-hc' : ''}.svg`; collector.addRule(` .monaco-workbench .part.editor > .content .editor-group-container.empty .editor-group-letterpress { - background-image: url('${getPathFromAmdModule(require, letterpress)}') + background-image: url('${FileAccess.asBrowserUri(letterpress, require).fsPath}') } `); diff --git a/src/vs/workbench/contrib/cli/node/cli.contribution.ts b/src/vs/workbench/contrib/cli/node/cli.contribution.ts index a0dfd14878af2..2000693fdf3e4 100644 --- a/src/vs/workbench/contrib/cli/node/cli.contribution.ts +++ b/src/vs/workbench/contrib/cli/node/cli.contribution.ts @@ -19,7 +19,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import Severity from 'vs/base/common/severity'; import { ILogService } from 'vs/platform/log/common/log'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; import { IProductService } from 'vs/platform/product/common/productService'; function ignore(code: string, value: T): (err: any) => Promise { @@ -29,7 +29,7 @@ function ignore(code: string, value: T): (err: any) => Promise { let _source: string | null = null; function getSource(): string { if (!_source) { - const root = getPathFromAmdModule(require, ''); + const root = FileAccess.asFileUri('', require).fsPath; _source = path.resolve(root, '..', 'bin', 'code'); } return _source; diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index a359e971221a9..009fe56029df6 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -52,7 +52,7 @@ import { DebugTitleContribution } from 'vs/workbench/contrib/debug/browser/debug import { Codicon } from 'vs/base/common/codicons'; import { registerColors } from 'vs/workbench/contrib/debug/browser/debugColors'; import { DebugEditorContribution } from 'vs/workbench/contrib/debug/browser/debugEditorContribution'; -import { getUriFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; const registry = Registry.as(WorkbenchActionRegistryExtensions.WorkbenchActions); const debugCategory = nls.localize('debugCategory', "Debug"); @@ -210,15 +210,15 @@ function registerCommandsAndActions(): void { }); }; - registerTouchBarEntry(StartAction.ID, StartAction.LABEL, 0, CONTEXT_IN_DEBUG_MODE.toNegated(), getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/continue-tb.png')); - registerTouchBarEntry(RunAction.ID, RunAction.LABEL, 1, CONTEXT_IN_DEBUG_MODE.toNegated(), getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/continue-without-debugging-tb.png')); - registerTouchBarEntry(CONTINUE_ID, CONTINUE_LABEL, 0, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/continue-tb.png')); - registerTouchBarEntry(PAUSE_ID, PAUSE_LABEL, 1, ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.notEquals('debugState', 'stopped')), getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/pause-tb.png')); - registerTouchBarEntry(STEP_OVER_ID, STEP_OVER_LABEL, 2, CONTEXT_IN_DEBUG_MODE, getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/stepover-tb.png')); - registerTouchBarEntry(STEP_INTO_ID, STEP_INTO_LABEL, 3, CONTEXT_IN_DEBUG_MODE, getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/stepinto-tb.png')); - registerTouchBarEntry(STEP_OUT_ID, STEP_OUT_LABEL, 4, CONTEXT_IN_DEBUG_MODE, getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/stepout-tb.png')); - registerTouchBarEntry(RESTART_SESSION_ID, RESTART_LABEL, 5, CONTEXT_IN_DEBUG_MODE, getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/restart-tb.png')); - registerTouchBarEntry(STOP_ID, STOP_LABEL, 6, CONTEXT_IN_DEBUG_MODE, getUriFromAmdModule(require, 'vs/workbench/contrib/debug/browser/media/stop-tb.png')); + registerTouchBarEntry(StartAction.ID, StartAction.LABEL, 0, CONTEXT_IN_DEBUG_MODE.toNegated(), FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/continue-tb.png', require)); + registerTouchBarEntry(RunAction.ID, RunAction.LABEL, 1, CONTEXT_IN_DEBUG_MODE.toNegated(), FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/continue-without-debugging-tb.png', require)); + registerTouchBarEntry(CONTINUE_ID, CONTINUE_LABEL, 0, CONTEXT_DEBUG_STATE.isEqualTo('stopped'), FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/continue-tb.png', require)); + registerTouchBarEntry(PAUSE_ID, PAUSE_LABEL, 1, ContextKeyExpr.and(CONTEXT_IN_DEBUG_MODE, ContextKeyExpr.notEquals('debugState', 'stopped')), FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/pause-tb.png', require)); + registerTouchBarEntry(STEP_OVER_ID, STEP_OVER_LABEL, 2, CONTEXT_IN_DEBUG_MODE, FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/stepover-tb.png', require)); + registerTouchBarEntry(STEP_INTO_ID, STEP_INTO_LABEL, 3, CONTEXT_IN_DEBUG_MODE, FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/stepinto-tb.png', require)); + registerTouchBarEntry(STEP_OUT_ID, STEP_OUT_LABEL, 4, CONTEXT_IN_DEBUG_MODE, FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/stepout-tb.png', require)); + registerTouchBarEntry(RESTART_SESSION_ID, RESTART_LABEL, 5, CONTEXT_IN_DEBUG_MODE, FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/restart-tb.png', require)); + registerTouchBarEntry(STOP_ID, STOP_LABEL, 6, CONTEXT_IN_DEBUG_MODE, FileAccess.asFileUri('vs/workbench/contrib/debug/browser/media/stop-tb.png', require)); } } diff --git a/src/vs/workbench/contrib/debug/node/debugHelperService.ts b/src/vs/workbench/contrib/debug/node/debugHelperService.ts index 4089f00771a59..a7bed36cf6199 100644 --- a/src/vs/workbench/contrib/debug/node/debugHelperService.ts +++ b/src/vs/workbench/contrib/debug/node/debugHelperService.ts @@ -6,7 +6,7 @@ import { IDebugHelperService } from 'vs/workbench/contrib/debug/common/debug'; import { Client as TelemetryClient } from 'vs/base/parts/ipc/node/ipc.cp'; import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; import { TelemetryService } from 'vs/platform/telemetry/common/telemetryService'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -24,7 +24,7 @@ export class NodeDebugHelperService implements IDebugHelperService { createTelemetryService(configurationService: IConfigurationService, args: string[]): TelemetryService | undefined { const client = new TelemetryClient( - getPathFromAmdModule(require, 'bootstrap-fork'), + FileAccess.asFileUri('bootstrap-fork', require).fsPath, { serverName: 'Debug Telemetry', timeout: 1000 * 60 * 5, diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts index 3d1fbe7f7a3da..7f1d1613edecc 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts @@ -40,6 +40,7 @@ import { asDomUri } from 'vs/base/browser/dom'; import { getIgnoredExtensions } from 'vs/platform/userDataSync/common/extensionsMerge'; import { isWeb } from 'vs/base/common/platform'; import { getExtensionKind } from 'vs/workbench/services/extensions/common/extensionsUtil'; +import { FileAccess } from 'vs/base/common/network'; interface IExtensionStateProvider { (extension: Extension): T; @@ -151,10 +152,10 @@ class Extension implements IExtension { if (this.type === ExtensionType.System && this.local) { if (this.local.manifest && this.local.manifest.contributes) { if (Array.isArray(this.local.manifest.contributes.themes) && this.local.manifest.contributes.themes.length) { - return require.toUrl('./media/theme-icon.png'); + return FileAccess.asBrowserUri('./media/theme-icon.png', require).toString(true); } if (Array.isArray(this.local.manifest.contributes.grammars) && this.local.manifest.contributes.grammars.length) { - return require.toUrl('./media/language-icon.svg'); + return FileAccess.asBrowserUri('./media/language-icon.svg', require).toString(true); } } } diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts index 989e89d8f3a3b..cc2d3cc596cee 100644 --- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts +++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts @@ -223,8 +223,8 @@ suite('ExtensionsWorkbenchServiceTest', () => { assert.equal('1.1.0', actual.version); assert.equal('1.1.0', actual.latestVersion); assert.equal('localDescription1', actual.description); - assert.equal('file:///localPath1/localIcon1', actual.iconUrl); - assert.equal('file:///localPath1/localIcon1', actual.iconUrlFallback); + assert.ok(actual.iconUrl === 'file:///localPath1/localIcon1' || actual.iconUrl === 'vscode-file://vscode-app/localPath1/localIcon1'); + assert.ok(actual.iconUrlFallback === 'file:///localPath1/localIcon1' || actual.iconUrlFallback === 'vscode-file://vscode-app/localPath1/localIcon1'); assert.equal(null, actual.licenseUrl); assert.equal(ExtensionState.Installed, actual.state); assert.equal(null, actual.installCount); diff --git a/src/vs/workbench/contrib/externalTerminal/node/externalTerminalService.ts b/src/vs/workbench/contrib/externalTerminal/node/externalTerminalService.ts index 9a55ddd4e97a1..3e0af5cc85453 100644 --- a/src/vs/workbench/contrib/externalTerminal/node/externalTerminalService.ts +++ b/src/vs/workbench/contrib/externalTerminal/node/externalTerminalService.ts @@ -11,9 +11,9 @@ import * as pfs from 'vs/base/node/pfs'; import * as env from 'vs/base/common/platform'; import { IExternalTerminalService, IExternalTerminalConfiguration, IExternalTerminalSettings } from 'vs/workbench/contrib/externalTerminal/common/externalTerminal'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { optional } from 'vs/platform/instantiation/common/instantiation'; import { DEFAULT_TERMINAL_OSX } from 'vs/workbench/contrib/externalTerminal/node/externalTerminal'; +import { FileAccess } from 'vs/base/common/network'; const TERMINAL_TITLE = nls.localize('console.title', "VS Code Console"); @@ -144,7 +144,7 @@ export class MacExternalTerminalService implements IExternalTerminalService { // and then launches the program inside that window. const script = terminalApp === DEFAULT_TERMINAL_OSX ? 'TerminalHelper' : 'iTermHelper'; - const scriptpath = getPathFromAmdModule(require, `vs/workbench/contrib/externalTerminal/node/${script}.scpt`); + const scriptpath = FileAccess.asFileUri(`vs/workbench/contrib/externalTerminal/node/${script}.scpt`, require).fsPath; const osaArgs = [ scriptpath, diff --git a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts index 92dab1a41f624..27bfc924f61ec 100644 --- a/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts +++ b/src/vs/workbench/contrib/webview/electron-browser/webviewElement.ts @@ -9,7 +9,7 @@ import { ThrottledDelayer } from 'vs/base/common/async'; import { Emitter, Event } from 'vs/base/common/event'; import { once } from 'vs/base/common/functional'; import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; -import { Schemas } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { isMacintosh } from 'vs/base/common/platform'; import { URI } from 'vs/base/common/uri'; import { createChannelSender } from 'vs/base/parts/ipc/common/ipc'; @@ -206,7 +206,10 @@ export class ElectronWebviewBasedWebview extends BaseWebview impleme this.styledFindWidget(); } - this.element!.preload = require.toUrl('./pre/electron-index.js'); + // We must ensure to put a `file:` URI as the preload attribute + // and not the `vscode-file` URI because preload scripts are loaded + // via node.js from the main side and only allow `file:` protocol + this.element!.preload = FileAccess.asFileUri('./pre/electron-index.js', require).toString(true); this.element!.src = `${Schemas.vscodeWebview}://${this.id}/electron-browser/index.html?platform=electron`; } diff --git a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts index 21731a88c9aa4..bfb78c17fdb2b 100644 --- a/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts +++ b/src/vs/workbench/contrib/welcome/page/browser/welcomePage.ts @@ -19,7 +19,7 @@ import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configur import { localize } from 'vs/nls'; import { Action, WorkbenchActionExecutedEvent, WorkbenchActionExecutedClassification } from 'vs/base/common/actions'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; -import { Schemas } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { IBackupFileService } from 'vs/workbench/services/backup/common/backup'; import { getInstalledExtensions, IExtensionStatus, onExtensionChanged, isKeymapExtension } from 'vs/workbench/contrib/extensions/common/extensionsUtils'; import { IExtensionManagementService, IExtensionGalleryService, ILocalExtension } from 'vs/platform/extensionManagement/common/extensionManagement'; @@ -46,7 +46,6 @@ import { IProductService } from 'vs/platform/product/common/productService'; import { IEditorOptions } from 'vs/platform/editor/common/editor'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet'; -import { getUriFromAmdModule } from 'vs/base/common/amd'; const configurationKey = 'workbench.startupEditor'; const oldConfigurationKey = 'workbench.welcome.enabled'; @@ -299,7 +298,7 @@ class WelcomePage extends Disposable { const recentlyOpened = this.workspacesService.getRecentlyOpened(); const installedExtensions = this.instantiationService.invokeFunction(getInstalledExtensions); - const resource = getUriFromAmdModule(require, './vs_code_welcome_page') + const resource = FileAccess.asBrowserUri('./vs_code_welcome_page', require) .with({ scheme: Schemas.walkThrough, query: JSON.stringify({ moduleId: 'vs/workbench/contrib/welcome/page/browser/vs_code_welcome_page' }) diff --git a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts index c02c5aadc859e..04a605f1cc318 100644 --- a/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts +++ b/src/vs/workbench/contrib/welcome/walkThrough/browser/editor/editorWalkThrough.ts @@ -8,16 +8,15 @@ import { localize } from 'vs/nls'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { Action } from 'vs/base/common/actions'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; -import { getUriFromAmdModule } from 'vs/base/common/amd'; import { WalkThroughInput, WalkThroughInputOptions } from 'vs/workbench/contrib/welcome/walkThrough/browser/walkThroughInput'; -import { Schemas } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import { IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor'; const typeId = 'workbench.editors.walkThroughInput'; const inputOptions: WalkThroughInputOptions = { typeId, name: localize('editorWalkThrough.title', "Interactive Playground"), - resource: getUriFromAmdModule(require, './vs_code_editor_walkthrough.md') + resource: FileAccess.asBrowserUri('./vs_code_editor_walkthrough.md', require) .with({ scheme: Schemas.walkThrough, query: JSON.stringify({ moduleId: 'vs/workbench/contrib/welcome/walkThrough/browser/editor/vs_code_editor_walkthrough' }) diff --git a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts index 52ad26825abaf..cb32f67a914cc 100644 --- a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts +++ b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts @@ -141,6 +141,7 @@ export class SimpleNativeWorkbenchEnvironmentService implements INativeWorkbench verbose = false; isBuilt = false; disableTelemetry = false; + v8CacheOptions: 'none' | 'code' | 'bypassHeatCheck' | 'bypassHeatCheckAndEagerCompile' = 'none'; } //#endregion diff --git a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts index 8740402bd1ca8..9b601619a503e 100644 --- a/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts +++ b/src/vs/workbench/services/extensions/browser/webWorkerExtensionHost.ts @@ -29,6 +29,7 @@ import { generateUuid } from 'vs/base/common/uuid'; import { canceled, onUnexpectedError } from 'vs/base/common/errors'; import { WEB_WORKER_IFRAME } from 'vs/workbench/services/extensions/common/webWorkerIframe'; import { Barrier } from 'vs/base/common/async'; +import { FileAccess } from 'vs/base/common/network'; export interface IWebWorkerExtensionHostInitData { readonly autoStart: boolean; @@ -92,7 +93,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost iframe.style.display = 'none'; const vscodeWebWorkerExtHostId = generateUuid(); - const workerUrl = require.toUrl('../worker/extensionHostWorkerMain.js'); + const workerUrl = FileAccess.asBrowserUri('../worker/extensionHostWorkerMain.js', require).toString(true); const workerSrc = getWorkerBootstrapUrl(workerUrl, 'WorkerExtensionHost', true); const escapeAttribute = (value: string): string => { return value.replace(/"/g, '"'); @@ -173,7 +174,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost private async _startOutsideIframe(): Promise { const emitter = new Emitter(); - const url = getWorkerBootstrapUrl(require.toUrl('../worker/extensionHostWorkerMain.js'), 'WorkerExtensionHost'); + const url = getWorkerBootstrapUrl(FileAccess.asBrowserUri('../worker/extensionHostWorkerMain.js', require).toString(true), 'WorkerExtensionHost'); const worker = new Worker(url, { name: 'WorkerExtensionHost' }); const barrier = new Barrier(); diff --git a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts index 600361d627501..2b68774b1503f 100644 --- a/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts +++ b/src/vs/workbench/services/extensions/electron-browser/cachedExtensionScanner.ts @@ -5,9 +5,8 @@ import * as nls from 'vs/nls'; import * as path from 'vs/base/common/path'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; import * as errors from 'vs/base/common/errors'; -import { Schemas } from 'vs/base/common/network'; +import { FileAccess, Schemas } from 'vs/base/common/network'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; import { joinPath, originalFSPath } from 'vs/base/common/resources'; @@ -30,7 +29,7 @@ interface IExtensionCacheData { let _SystemExtensionsRoot: string | null = null; function getSystemExtensionsRoot(): string { if (!_SystemExtensionsRoot) { - _SystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'extensions')); + _SystemExtensionsRoot = path.normalize(path.join(FileAccess.asFileUri('', require).fsPath, '..', 'extensions')); } return _SystemExtensionsRoot; } @@ -38,7 +37,7 @@ function getSystemExtensionsRoot(): string { let _ExtraDevSystemExtensionsRoot: string | null = null; function getExtraDevSystemExtensionsRoot(): string { if (!_ExtraDevSystemExtensionsRoot) { - _ExtraDevSystemExtensionsRoot = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', '.build', 'builtInExtensions')); + _ExtraDevSystemExtensionsRoot = path.normalize(path.join(FileAccess.asFileUri('', require).fsPath, '..', '.build', 'builtInExtensions')); } return _ExtraDevSystemExtensionsRoot; } diff --git a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts index fcb8ffa9a05d8..a92220fc8d66e 100644 --- a/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts +++ b/src/vs/workbench/services/extensions/electron-browser/localProcessExtensionHost.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { ChildProcess, fork } from 'child_process'; import { Server, Socket, createServer } from 'net'; import { CrashReporterStartOptions } from 'vs/base/parts/sandbox/electron-sandbox/electronTypes'; -import { getPathFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; import { timeout } from 'vs/base/common/async'; import { toErrorMessage } from 'vs/base/common/errorMessage'; import { Emitter, Event } from 'vs/base/common/event'; @@ -215,7 +215,7 @@ export class LocalProcessExtensionHost implements IExtensionHost { } // Run Extension Host as fork of current process - this._extensionHostProcess = fork(getPathFromAmdModule(require, 'bootstrap-fork'), ['--type=extensionHost'], opts); + this._extensionHostProcess = fork(FileAccess.asFileUri('bootstrap-fork', require).fsPath, ['--type=extensionHost'], opts); // Catch all output coming from the extension host process type Output = { data: string, format: string[] }; diff --git a/src/vs/workbench/services/integrity/node/integrityService.ts b/src/vs/workbench/services/integrity/node/integrityService.ts index cd348ebef866b..7d50386ce6fcb 100644 --- a/src/vs/workbench/services/integrity/node/integrityService.ts +++ b/src/vs/workbench/services/integrity/node/integrityService.ts @@ -15,7 +15,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IOpenerService } from 'vs/platform/opener/common/opener'; -import { getUriFromAmdModule } from 'vs/base/common/amd'; +import { FileAccess } from 'vs/base/common/network'; interface IStorageData { dontShowPrompt: boolean; @@ -142,7 +142,7 @@ export class IntegrityServiceImpl implements IIntegrityService { } private _resolve(filename: string, expected: string): Promise { - const fileUri = getUriFromAmdModule(require, filename); + const fileUri = FileAccess.asFileUri(filename, require); return new Promise((resolve, reject) => { fs.readFile(fileUri.fsPath, (err, buff) => { if (err) { diff --git a/src/vs/workbench/services/search/electron-browser/searchService.ts b/src/vs/workbench/services/search/electron-browser/searchService.ts index 45ed77c6a428b..ea15e40b57f64 100644 --- a/src/vs/workbench/services/search/electron-browser/searchService.ts +++ b/src/vs/workbench/services/search/electron-browser/searchService.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { getPathFromAmdModule } from 'vs/base/common/amd'; import { CancellationToken } from 'vs/base/common/cancellation'; import { canceled } from 'vs/base/common/errors'; import { Event } from 'vs/base/common/event'; @@ -26,6 +25,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; +import { FileAccess } from 'vs/base/common/network'; export class LocalSearchService extends SearchService { constructor( @@ -82,10 +82,7 @@ export class DiskSearch implements ISearchResultProvider { } } - const client = new Client( - getPathFromAmdModule(require, 'bootstrap-fork'), - opts); - + const client = new Client(FileAccess.asFileUri('bootstrap-fork', require).fsPath, opts); const channel = getNextTickChannel(client.getChannel('search')); this.raw = new SearchChannelClient(channel); } diff --git a/src/vs/workbench/services/textMate/browser/textMateService.ts b/src/vs/workbench/services/textMate/browser/textMateService.ts index ed781d238448d..5a594121bf42a 100644 --- a/src/vs/workbench/services/textMate/browser/textMateService.ts +++ b/src/vs/workbench/services/textMate/browser/textMateService.ts @@ -14,6 +14,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IStorageService } from 'vs/platform/storage/common/storage'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { IProgressService } from 'vs/platform/progress/common/progress'; +import { FileAccess } from 'vs/base/common/network'; export class TextMateService extends AbstractTextMateService { @@ -31,8 +32,7 @@ export class TextMateService extends AbstractTextMateService { } protected async _loadVSCodeOnigurumWASM(): Promise { - const wasmPath = require.toUrl('vscode-oniguruma/../onig.wasm'); - const response = await fetch(wasmPath); + const response = await fetch(FileAccess.asBrowserUri('vscode-oniguruma/../onig.wasm', require).toString(true)); // Using the response directly only works if the server sets the MIME type 'application/wasm'. // Otherwise, a TypeError is thrown when using the streaming compiler. // We therefore use the non-streaming compiler :(. diff --git a/src/vs/workbench/services/textMate/electron-sandbox/textMateService.ts b/src/vs/workbench/services/textMate/electron-sandbox/textMateService.ts index 57f6cda672659..209e19fbb5bcf 100644 --- a/src/vs/workbench/services/textMate/electron-sandbox/textMateService.ts +++ b/src/vs/workbench/services/textMate/electron-sandbox/textMateService.ts @@ -26,6 +26,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { IExtensionResourceLoaderService } from 'vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { IProgressService } from 'vs/platform/progress/common/progress'; +import { FileAccess } from 'vs/base/common/network'; const RUN_TEXTMATE_IN_WORKER = false; @@ -182,12 +183,9 @@ export class TextMateService extends AbstractTextMateService { } protected async _loadVSCodeOnigurumWASM(): Promise { - const wasmPath = ( - this._environmentService.isBuilt - ? require.toUrl('../../../../../../node_modules.asar.unpacked/vscode-oniguruma/release/onig.wasm') - : require.toUrl('../../../../../../node_modules/vscode-oniguruma/release/onig.wasm') - ); - const response = await fetch(wasmPath); + const response = await fetch(this._environmentService.isBuilt + ? FileAccess.asBrowserUri('../../../../../../node_modules.asar.unpacked/vscode-oniguruma/release/onig.wasm', require).toString(true) + : FileAccess.asBrowserUri('../../../../../../node_modules/vscode-oniguruma/release/onig.wasm', require).toString(true)); return response; } diff --git a/src/vs/workbench/services/textMate/electron-sandbox/textMateWorker.ts b/src/vs/workbench/services/textMate/electron-sandbox/textMateWorker.ts index bf62c5393a902..5b811274fbcc0 100644 --- a/src/vs/workbench/services/textMate/electron-sandbox/textMateWorker.ts +++ b/src/vs/workbench/services/textMate/electron-sandbox/textMateWorker.ts @@ -14,6 +14,7 @@ import { TokenizationStateStore } from 'vs/editor/common/model/textModelTokens'; import type { IGrammar, StackElement, IRawTheme, IOnigLib } from 'vscode-textmate'; import { MultilineTokensBuilder, countEOL } from 'vs/editor/common/model/tokensStore'; import { LineTokens } from 'vs/editor/common/core/lineTokens'; +import { FileAccess } from 'vs/base/common/network'; export interface IValidGrammarDefinitionDTO { location: UriComponents; @@ -146,8 +147,7 @@ export class TextMateWorker { }); const vscodeTextmate = await import('vscode-textmate'); const vscodeOniguruma = await import('vscode-oniguruma'); - const wasmPath = require.toUrl('vscode-oniguruma/../onig.wasm'); - const response = await fetch(wasmPath); + const response = await fetch(FileAccess.asBrowserUri('vscode-oniguruma/../onig.wasm', require).toString(true)); // Using the response directly only works if the server sets the MIME type 'application/wasm'. // Otherwise, a TypeError is thrown when using the streaming compiler. // We therefore use the non-streaming compiler :(. diff --git a/test/unit/electron/renderer.js b/test/unit/electron/renderer.js index 3f29ac6cfa82e..a1b6ef62746cb 100644 --- a/test/unit/electron/renderer.js +++ b/test/unit/electron/renderer.js @@ -32,7 +32,7 @@ function initLoader(opts) { nodeRequire: require, nodeMain: __filename, catchError: true, - baseUrl: bootstrap.fileUriFromPath(path.join(__dirname, '../../../src'), process.platform === 'win32'), + baseUrl: bootstrap.fileUriFromPath(path.join(__dirname, '../../../src'), { isWindows: process.platform === 'win32' }), paths: { 'vs': `../${outdir}/vs`, 'lib': `../${outdir}/lib`,