From e649ef370107ae8249a7912b59a5c0f621f7a18d Mon Sep 17 00:00:00 2001 From: Benjamin Pasero Date: Tue, 22 Sep 2020 08:49:11 +0200 Subject: [PATCH] sandbox - function scope for workbench too --- .../electron-browser/workbench/workbench.js | 319 +++++++++--------- .../electron-sandbox/workbench/workbench.js | 135 ++++---- 2 files changed, 240 insertions(+), 214 deletions(-) diff --git a/src/vs/code/electron-browser/workbench/workbench.js b/src/vs/code/electron-browser/workbench/workbench.js index 473ffdad848..3dd6691d3a0 100644 --- a/src/vs/code/electron-browser/workbench/workbench.js +++ b/src/vs/code/electron-browser/workbench/workbench.js @@ -8,171 +8,184 @@ //@ts-check 'use strict'; -const perf = (function () { - globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || []; - return { - /** - * @param {string} name - */ - mark(name) { - globalThis.MonacoPerformanceMarks.push(name, Date.now()); - } - }; -})(); - -perf.mark('renderer/started'); - -/** - * @type {{ - * load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown, - * globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals') - * }} - */ -const bootstrapWindow = (() => { - // @ts-ignore (defined in bootstrap-window.js) - return window.MonacoBootstrapWindow; -})(); - -// Load environment in parallel to workbench loading to avoid waterfall -const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved(); - -// Load workbench main JS, CSS and NLS all in parallel. This is an -// optimization to prevent a waterfall of loading to happen, because -// we know for a fact that workbench.desktop.main will depend on -// the related CSS and NLS counterparts. -bootstrapWindow.load([ - 'vs/workbench/workbench.desktop.main', - 'vs/nls!vs/workbench/workbench.desktop.main', - 'vs/css!vs/workbench/workbench.desktop.main' -], - async function (workbench, configuration) { - - // Mark start of workbench - perf.mark('didLoadWorkbenchMain'); - performance.mark('workbench-start'); - - // Wait for process environment being fully resolved - await whenEnvResolved; - - perf.mark('main/startup'); - - // @ts-ignore - return require('vs/workbench/electron-browser/desktop.main').main(configuration); - }, - { - removeDeveloperKeybindingsAfterLoad: true, - canModifyDOM: function (windowConfig) { - showPartsSplash(windowConfig); - }, - beforeLoaderConfig: function (windowConfig, loaderConfig) { - loaderConfig.recordStats = true; +(function () { + + // Add a perf entry right from the top + const perf = perfLib(); + perf.mark('renderer/started'); + + // Load environment in parallel to workbench loading to avoid waterfall + const bootstrapWindow = bootstrapWindowLib(); + const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved(); + + // Load workbench main JS, CSS and NLS all in parallel. This is an + // optimization to prevent a waterfall of loading to happen, because + // we know for a fact that workbench.desktop.main will depend on + // the related CSS and NLS counterparts. + bootstrapWindow.load([ + 'vs/workbench/workbench.desktop.main', + 'vs/nls!vs/workbench/workbench.desktop.main', + 'vs/css!vs/workbench/workbench.desktop.main' + ], + async function (workbench, configuration) { + + // Mark start of workbench + perf.mark('didLoadWorkbenchMain'); + performance.mark('workbench-start'); + + // Wait for process environment being fully resolved + await whenEnvResolved; + + perf.mark('main/startup'); + + // @ts-ignore + return require('vs/workbench/electron-browser/desktop.main').main(configuration); }, - beforeRequire: function () { - perf.mark('willLoadWorkbenchMain'); - } - } -); - -/** - * @param {{ - * partsSplashPath?: string, - * colorScheme: ('light' | 'dark' | 'hc'), - * autoDetectHighContrast?: boolean, - * extensionDevelopmentPath?: string[], - * folderUri?: object, - * workspace?: object - * }} configuration - */ -function showPartsSplash(configuration) { - perf.mark('willShowPartsSplash'); - - let data; - if (typeof configuration.partsSplashPath === 'string') { - try { - data = JSON.parse(require.__$__nodeRequire('fs').readFileSync(configuration.partsSplashPath, 'utf8')); - } catch (e) { - // ignore + { + removeDeveloperKeybindingsAfterLoad: true, + canModifyDOM: function (windowConfig) { + showPartsSplash(windowConfig); + }, + beforeLoaderConfig: function (windowConfig, loaderConfig) { + loaderConfig.recordStats = true; + }, + beforeRequire: function () { + perf.mark('willLoadWorkbenchMain'); + } } - } + ); - // high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts - const isHighContrast = configuration.colorScheme === 'hc' /* ColorScheme.HIGH_CONTRAST */ && configuration.autoDetectHighContrast; - if (data && isHighContrast && data.baseTheme !== 'hc-black') { - data = undefined; - } - // developing an extension -> ignore stored layouts - if (data && configuration.extensionDevelopmentPath) { - data.layoutInfo = undefined; + //region Helpers + + function perfLib() { + globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || []; + + return { + /** + * @param {string} name + */ + mark(name) { + globalThis.MonacoPerformanceMarks.push(name, Date.now()); + } + }; } - // minimal color configuration (works with or without persisted data) - let baseTheme, shellBackground, shellForeground; - if (data) { - baseTheme = data.baseTheme; - shellBackground = data.colorInfo.editorBackground; - shellForeground = data.colorInfo.foreground; - } else if (isHighContrast) { - baseTheme = 'hc-black'; - shellBackground = '#000000'; - shellForeground = '#FFFFFF'; - } else { - baseTheme = 'vs-dark'; - shellBackground = '#1E1E1E'; - shellForeground = '#CCCCCC'; + /** + * @returns {{ + * load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown, + * globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals') + * }} + */ + function bootstrapWindowLib() { + // @ts-ignore (defined in bootstrap-window.js) + return window.MonacoBootstrapWindow; } - const style = document.createElement('style'); - style.className = 'initialShellColors'; - document.head.appendChild(style); - style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; - - if (data && data.layoutInfo) { - // restore parts if possible (we might not always store layout info) - const { id, layoutInfo, colorInfo } = data; - const splash = document.createElement('div'); - splash.id = id; - splash.className = baseTheme; - - if (layoutInfo.windowBorder) { - splash.style.position = 'relative'; - splash.style.height = 'calc(100vh - 2px)'; - splash.style.width = 'calc(100vw - 2px)'; - splash.style.border = '1px solid var(--window-border-color)'; - splash.style.setProperty('--window-border-color', colorInfo.windowBorder); - - if (layoutInfo.windowBorderRadius) { - splash.style.borderRadius = layoutInfo.windowBorderRadius; + + /** + * @param {{ + * partsSplashPath?: string, + * colorScheme: ('light' | 'dark' | 'hc'), + * autoDetectHighContrast?: boolean, + * extensionDevelopmentPath?: string[], + * folderUri?: object, + * workspace?: object + * }} configuration + */ + function showPartsSplash(configuration) { + perf.mark('willShowPartsSplash'); + + let data; + if (typeof configuration.partsSplashPath === 'string') { + try { + data = JSON.parse(require.__$__nodeRequire('fs').readFileSync(configuration.partsSplashPath, 'utf8')); + } catch (e) { + // ignore } } - // ensure there is enough space - layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); - - // part: title - const titleDiv = document.createElement('div'); - titleDiv.setAttribute('style', `position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;`); - splash.appendChild(titleDiv); - - // part: activity bar - const activityDiv = document.createElement('div'); - activityDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};`); - splash.appendChild(activityDiv); - - // part: side bar (only when opening workspace/folder) - if (configuration.folderUri || configuration.workspace) { - // folder or workspace -> status bar color, sidebar - const sideDiv = document.createElement('div'); - sideDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: ${layoutInfo.activityBarWidth}px; width: ${layoutInfo.sideBarWidth}px; background-color: ${colorInfo.sideBarBackground};`); - splash.appendChild(sideDiv); + // high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts + const isHighContrast = configuration.colorScheme === 'hc' /* ColorScheme.HIGH_CONTRAST */ && configuration.autoDetectHighContrast; + if (data && isHighContrast && data.baseTheme !== 'hc-black') { + data = undefined; + } + + // developing an extension -> ignore stored layouts + if (data && configuration.extensionDevelopmentPath) { + data.layoutInfo = undefined; + } + + // minimal color configuration (works with or without persisted data) + let baseTheme, shellBackground, shellForeground; + if (data) { + baseTheme = data.baseTheme; + shellBackground = data.colorInfo.editorBackground; + shellForeground = data.colorInfo.foreground; + } else if (isHighContrast) { + baseTheme = 'hc-black'; + shellBackground = '#000000'; + shellForeground = '#FFFFFF'; + } else { + baseTheme = 'vs-dark'; + shellBackground = '#1E1E1E'; + shellForeground = '#CCCCCC'; } + const style = document.createElement('style'); + style.className = 'initialShellColors'; + document.head.appendChild(style); + style.textContent = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`; + + if (data && data.layoutInfo) { + // restore parts if possible (we might not always store layout info) + const { id, layoutInfo, colorInfo } = data; + const splash = document.createElement('div'); + splash.id = id; + splash.className = baseTheme; + + if (layoutInfo.windowBorder) { + splash.style.position = 'relative'; + splash.style.height = 'calc(100vh - 2px)'; + splash.style.width = 'calc(100vw - 2px)'; + splash.style.border = '1px solid var(--window-border-color)'; + splash.style.setProperty('--window-border-color', colorInfo.windowBorder); + + if (layoutInfo.windowBorderRadius) { + splash.style.borderRadius = layoutInfo.windowBorderRadius; + } + } + + // ensure there is enough space + layoutInfo.sideBarWidth = Math.min(layoutInfo.sideBarWidth, window.innerWidth - (layoutInfo.activityBarWidth + layoutInfo.editorPartMinWidth)); + + // part: title + const titleDiv = document.createElement('div'); + titleDiv.setAttribute('style', `position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;`); + splash.appendChild(titleDiv); + + // part: activity bar + const activityDiv = document.createElement('div'); + activityDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};`); + splash.appendChild(activityDiv); + + // part: side bar (only when opening workspace/folder) + if (configuration.folderUri || configuration.workspace) { + // folder or workspace -> status bar color, sidebar + const sideDiv = document.createElement('div'); + sideDiv.setAttribute('style', `position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: ${layoutInfo.activityBarWidth}px; width: ${layoutInfo.sideBarWidth}px; background-color: ${colorInfo.sideBarBackground};`); + splash.appendChild(sideDiv); + } - // part: statusbar - const statusDiv = document.createElement('div'); - statusDiv.setAttribute('style', `position: absolute; width: 100%; bottom: 0; left: 0; height: ${layoutInfo.statusBarHeight}px; background-color: ${configuration.folderUri || configuration.workspace ? colorInfo.statusBarBackground : colorInfo.statusBarNoFolderBackground};`); - splash.appendChild(statusDiv); + // part: statusbar + const statusDiv = document.createElement('div'); + statusDiv.setAttribute('style', `position: absolute; width: 100%; bottom: 0; left: 0; height: ${layoutInfo.statusBarHeight}px; background-color: ${configuration.folderUri || configuration.workspace ? colorInfo.statusBarBackground : colorInfo.statusBarNoFolderBackground};`); + splash.appendChild(statusDiv); + + document.body.appendChild(splash); + } - document.body.appendChild(splash); + perf.mark('didShowPartsSplash'); } - perf.mark('didShowPartsSplash'); -} + //#endregion + +}()); diff --git a/src/vs/code/electron-sandbox/workbench/workbench.js b/src/vs/code/electron-sandbox/workbench/workbench.js index 63279645fbe..3966a9d0eac 100644 --- a/src/vs/code/electron-sandbox/workbench/workbench.js +++ b/src/vs/code/electron-sandbox/workbench/workbench.js @@ -8,67 +8,80 @@ //@ts-check 'use strict'; -const perf = (function () { - globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || []; - return { - /** - * @param {string} name - */ - mark(name) { - globalThis.MonacoPerformanceMarks.push(name, Date.now()); - } - }; -})(); - -perf.mark('renderer/started'); - -/** - * @type {{ - * load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown, - * globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals') - * }} - */ -const bootstrapWindow = (() => { - // @ts-ignore (defined in bootstrap-window.js) - return window.MonacoBootstrapWindow; -})(); - -// Load environment in parallel to workbench loading to avoid waterfall -const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved(); - -// Load workbench main JS, CSS and NLS all in parallel. This is an -// optimization to prevent a waterfall of loading to happen, because -// we know for a fact that workbench.desktop.sandbox.main will depend on -// the related CSS and NLS counterparts. -bootstrapWindow.load([ - 'vs/workbench/workbench.desktop.sandbox.main', - 'vs/nls!vs/workbench/workbench.desktop.main', - 'vs/css!vs/workbench/workbench.desktop.main' -], - async function (workbench, configuration) { - - // Mark start of workbench - perf.mark('didLoadWorkbenchMain'); - performance.mark('workbench-start'); - - // Wait for process environment being fully resolved - await whenEnvResolved; - - perf.mark('main/startup'); - - // @ts-ignore - return require('vs/workbench/electron-sandbox/desktop.main').main(configuration); - }, - { - removeDeveloperKeybindingsAfterLoad: true, - canModifyDOM: function (windowConfig) { - // TODO@sandbox part-splash is non-sandboxed only - }, - beforeLoaderConfig: function (windowConfig, loaderConfig) { - loaderConfig.recordStats = true; +(function () { + + // Add a perf entry right from the top + const perf = perfLib(); + perf.mark('renderer/started'); + + // Load environment in parallel to workbench loading to avoid waterfall + const bootstrapWindow = bootstrapWindowLib(); + const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved(); + + // Load workbench main JS, CSS and NLS all in parallel. This is an + // optimization to prevent a waterfall of loading to happen, because + // we know for a fact that workbench.desktop.sandbox.main will depend on + // the related CSS and NLS counterparts. + bootstrapWindow.load([ + 'vs/workbench/workbench.desktop.sandbox.main', + 'vs/nls!vs/workbench/workbench.desktop.main', + 'vs/css!vs/workbench/workbench.desktop.main' + ], + async function (workbench, configuration) { + + // Mark start of workbench + perf.mark('didLoadWorkbenchMain'); + performance.mark('workbench-start'); + + // Wait for process environment being fully resolved + await whenEnvResolved; + + perf.mark('main/startup'); + + // @ts-ignore + return require('vs/workbench/electron-sandbox/desktop.main').main(configuration); }, - beforeRequire: function () { - perf.mark('willLoadWorkbenchMain'); + { + removeDeveloperKeybindingsAfterLoad: true, + canModifyDOM: function (windowConfig) { + // TODO@sandbox part-splash is non-sandboxed only + }, + beforeLoaderConfig: function (windowConfig, loaderConfig) { + loaderConfig.recordStats = true; + }, + beforeRequire: function () { + perf.mark('willLoadWorkbenchMain'); + } } + ); + + + //region Helpers + + function perfLib() { + globalThis.MonacoPerformanceMarks = globalThis.MonacoPerformanceMarks || []; + + return { + /** + * @param {string} name + */ + mark(name) { + globalThis.MonacoPerformanceMarks.push(name, Date.now()); + } + }; } -); + + /** + * @returns {{ + * load: (modules: string[], resultCallback: (result, configuration: object) => any, options: object) => unknown, + * globals: () => typeof import('../../../base/parts/sandbox/electron-sandbox/globals') + * }} + */ + function bootstrapWindowLib() { + // @ts-ignore (defined in bootstrap-window.js) + return window.MonacoBootstrapWindow; + } + + //#endregion + +}()); -- GitLab