diff --git a/src/bootstrap-window.js b/src/bootstrap-window.js index 0cc92ec..43042d5 100644 --- a/src/bootstrap-window.js +++ b/src/bootstrap-window.js @@ -24,6 +24,7 @@ const bootstrapLib = bootstrap(); const preloadGlobals = sandboxGlobals(); const safeProcess = preloadGlobals.process; + const useCustomProtocol = safeProcess.sandboxed; /** * @typedef {import('./vs/base/parts/sandbox/common/sandboxTypes').ISandboxConfiguration} ISandboxConfiguration @@ -99,6 +100,11 @@ window.document.documentElement.setAttribute('lang', locale); + // Do not advertise AMD to avoid confusing UMD modules loaded with nodejs + if (!useCustomProtocol) { + window['define'] = undefined; + } + // Replace the patched electron fs with the original node fs for all AMD code (TODO@sandbox non-sandboxed only) if (!safeProcess.sandboxed) { require.define('fs', [], function () { return require.__$__nodeRequire('original-fs'); }); @@ -107,9 +113,11 @@ window['MonacoEnvironment'] = {}; const loaderConfig = { - baseUrl: `${bootstrapLib.fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out`, + baseUrl: useCustomProtocol ? + `${bootstrapLib.fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32', scheme: 'vscode-file', fallbackAuthority: 'vscode-app' })}/out` : + `${bootstrapLib.fileUriFromPath(configuration.appRoot, { isWindows: safeProcess.platform === 'win32' })}/out`, 'vs/nls': nlsConfig, - preferScriptTags: true + preferScriptTags: useCustomProtocol }; // use a trusted types policy when loading via script tags @@ -143,6 +151,14 @@ loaderConfig.amdModulesPattern = /^vs\//; } + // Cached data config (node.js loading only) + if (!useCustomProtocol && configuration.codeCachePath) { + loaderConfig.nodeCachedData = { + path: configuration.codeCachePath, + seed: modulePaths.join('') + }; + } + // Signal before require.config() if (typeof options?.beforeLoaderConfig === 'function') { options.beforeLoaderConfig(loaderConfig); diff --git a/src/vs/base/common/network.ts b/src/vs/base/common/network.ts index 41a3fe9..bbb06e3 100644 --- a/src/vs/base/common/network.ts +++ b/src/vs/base/common/network.ts @@ -166,16 +166,7 @@ class FileAccessImpl { } // Convert to `vscode-file` resource.. - if ( - // ...only ever for `file` resources - uri.scheme === Schemas.file && - ( - // ...and we run in native environments - platform.isNative || - // ...or web worker extensions on desktop - (typeof platform.globals.importScripts === 'function' && platform.globals.origin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`) - ) - ) { + if (uri.scheme === Schemas.file && typeof platform.globals.importScripts === 'function' && platform.globals.origin === `${Schemas.vscodeFileResource}://${FileAccessImpl.FALLBACK_AUTHORITY}`) { return uri.with({ scheme: Schemas.vscodeFileResource, // We need to provide an authority here so that it can serve diff --git a/src/vs/platform/protocol/electron-main/protocolMainService.ts b/src/vs/platform/protocol/electron-main/protocolMainService.ts index bde08d8..3f09ad1 100644 --- a/src/vs/platform/protocol/electron-main/protocolMainService.ts +++ b/src/vs/platform/protocol/electron-main/protocolMainService.ts @@ -72,9 +72,24 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ //#region file:// private handleFileRequest(request: Electron.ProtocolRequest, callback: ProtocolCallback) { - const uri = URI.parse(request.url); + const fileUri = URI.parse(request.url); + + // first check by validRoots + if (this.validRoots.findSubstr(fileUri)) { + return callback({ + path: fileUri.fsPath + }); + } - this.logService.error(`Refused to load resource ${uri.fsPath} from ${Schemas.file}: protocol (original URL: ${request.url})`); + // then check by validExtensions + if (this.validExtensions.has(extname(fileUri))) { + return callback({ + path: fileUri.fsPath + }); + } + + // finally block to load the resource + this.logService.error(`${Schemas.file}: Refused to load resource ${fileUri.fsPath} from ${Schemas.file}: protocol (original URL: ${request.url})`); return callback({ error: -3 /* ABORTED */ }); } diff --git a/src/vs/workbench/services/timer/electron-sandbox/timerService.ts b/src/vs/workbench/services/timer/electron-sandbox/timerService.ts index 7cae207..1c54ac9 100644 --- a/src/vs/workbench/services/timer/electron-sandbox/timerService.ts +++ b/src/vs/workbench/services/timer/electron-sandbox/timerService.ts @@ -19,7 +19,7 @@ import { process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService'; import { IProductService } from 'vs/platform/product/common/productService'; -import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; +import { IStorageService } from 'vs/platform/storage/common/storage'; export class TimerService extends AbstractTimerService { @@ -91,24 +91,23 @@ registerSingleton(ITimerService, TimerService); //#region cached data logic -const lastRunningCommitStorageKey = 'perf/lastRunningCommit'; -let _didUseCachedData: boolean | undefined = undefined; - export function didUseCachedData(productService: IProductService, storageService: IStorageService, environmentService: INativeWorkbenchEnvironmentService): boolean { - // browser code loading: only a guess based on - // this being the first start with the commit - // or subsequent - if (typeof _didUseCachedData !== 'boolean') { - if (!environmentService.configuration.codeCachePath || !productService.commit) { - _didUseCachedData = false; // we only produce cached data whith commit and code cache path - } else if (storageService.get(lastRunningCommitStorageKey, StorageScope.GLOBAL) === productService.commit) { - _didUseCachedData = true; // subsequent start on same commit, assume cached data is there - } else { - storageService.store(lastRunningCommitStorageKey, productService.commit, StorageScope.GLOBAL, StorageTarget.MACHINE); - _didUseCachedData = false; // first time start on commit, assume cached data is not yet there + if (!Boolean((window).require.getConfig().nodeCachedData)) { + return false; + } + // There are loader events that signal if cached data was missing, rejected, + // or used. The former two mean no cached data. + let cachedDataFound = 0; + for (const event of require.getStats()) { + switch (event.type) { + case LoaderEventType.CachedDataRejected: + return false; + case LoaderEventType.CachedDataFound: + cachedDataFound += 1; + break; } } - return _didUseCachedData; + return cachedDataFound > 0; } //#endregion