Merge from vscode 7eaf220cafb9d9e901370ffce02229171cbf3ea6

This commit is contained in:
ADS Merger
2020-09-03 02:34:56 +00:00
committed by Anthony Dresser
parent 39d9eed585
commit a63578e6f7
519 changed files with 14338 additions and 6670 deletions

View File

@@ -682,6 +682,20 @@
"**/{vs,sql}/workbench/services/**/{common,browser}/**" "**/{vs,sql}/workbench/services/**/{common,browser}/**"
] ]
}, },
{
"target": "**/{vs,sql}/workbench/contrib/notebook/common/**",
"restrictions": [
"vs/nls",
"vs/css!./**/*",
"**/vs/base/**/{common,worker}/**",
"**/vs/platform/**/common/**",
"**/vs/editor/**",
"**/vs/workbench/common/**",
"**/vs/workbench/api/common/**",
"**/vs/workbench/services/**/common/**",
"**/vs/workbench/contrib/**/common/**"
]
},
{ {
"target": "**/{vs,sql}/workbench/contrib/**/common/**", "target": "**/{vs,sql}/workbench/contrib/**/common/**",
"restrictions": [ "restrictions": [

3
.vscode/launch.json vendored
View File

@@ -19,7 +19,8 @@
"timeout": 30000, "timeout": 30000,
"port": 5870, "port": 5870,
"outFiles": [ "outFiles": [
"${workspaceFolder}/out/**/*.js" "${workspaceFolder}/out/**/*.js",
"${workspaceFolder}/extensions/*/out/**/*.js"
] ]
}, },
{ {

16
.vscode/tasks.json vendored
View File

@@ -139,7 +139,7 @@
"label": "Kill Build Web Extensions", "label": "Kill Build Web Extensions",
"group": "build", "group": "build",
"presentation": { "presentation": {
"reveal": "never", "reveal": "never"
}, },
"problemMatcher": "$tsc" "problemMatcher": "$tsc"
}, },
@@ -209,5 +209,19 @@
"reveal": "silent" "reveal": "silent"
} }
}, },
{
"type": "npm",
"script": "tsec-compile-check",
"problemMatcher": [
{
"base": "$tsc",
"applyTo": "allDocuments",
"owner": "tsec"
},
],
"group": "build",
"label": "npm: tsec-compile-check",
"detail": "node_modules/tsec/bin/tsec -p src/tsconfig.json --noEmit"
}
] ]
} }

View File

@@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron" disturl "https://atom.io/download/electron"
target "9.2.0" target "9.2.1"
runtime "electron" runtime "electron"

View File

@@ -42,6 +42,7 @@ const vscodeEntryPoints = _.flatten([
buildfile.entrypoint('vs/workbench/workbench.desktop.main'), buildfile.entrypoint('vs/workbench/workbench.desktop.main'),
buildfile.base, buildfile.base,
buildfile.workerExtensionHost, buildfile.workerExtensionHost,
buildfile.workerNotebook,
buildfile.workbenchDesktop, buildfile.workbenchDesktop,
buildfile.code buildfile.code
]); ]);

View File

@@ -53,7 +53,9 @@ function createAsar(folderPath, unpackGlobs, destFilename) {
const insertFile = (relativePath, stat, shouldUnpack) => { const insertFile = (relativePath, stat, shouldUnpack) => {
insertDirectoryForFile(relativePath); insertDirectoryForFile(relativePath);
pendingInserts++; pendingInserts++;
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted); // Do not pass `onFileInserted` directly because it gets overwritten below.
// Create a closure capturing `onFileInserted`.
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}).then(() => onFileInserted(), () => onFileInserted());
}; };
return es.through(function (file) { return es.through(function (file) {
if (file.stat.isDirectory()) { if (file.stat.isDirectory()) {

View File

@@ -8,10 +8,17 @@
import * as path from 'path'; import * as path from 'path';
import * as es from 'event-stream'; import * as es from 'event-stream';
const pickle = require('chromium-pickle-js'); const pickle = require('chromium-pickle-js');
const Filesystem = require('asar/lib/filesystem'); const Filesystem = <typeof AsarFilesystem>require('asar/lib/filesystem');
import * as VinylFile from 'vinyl'; import * as VinylFile from 'vinyl';
import * as minimatch from 'minimatch'; import * as minimatch from 'minimatch';
declare class AsarFilesystem {
readonly header: unknown;
constructor(src: string);
insertDirectory(path: string, shouldUnpack?: boolean): unknown;
insertFile(path: string, shouldUnpack: boolean, file: { stat: { size: number; mode: number; }; }, options: {}): Promise<void>;
}
export function createAsar(folderPath: string, unpackGlobs: string[], destFilename: string): NodeJS.ReadWriteStream { export function createAsar(folderPath: string, unpackGlobs: string[], destFilename: string): NodeJS.ReadWriteStream {
const shouldUnpackFile = (file: VinylFile): boolean => { const shouldUnpackFile = (file: VinylFile): boolean => {
@@ -61,7 +68,9 @@ export function createAsar(folderPath: string, unpackGlobs: string[], destFilena
const insertFile = (relativePath: string, stat: { size: number; mode: number; }, shouldUnpack: boolean) => { const insertFile = (relativePath: string, stat: { size: number; mode: number; }, shouldUnpack: boolean) => {
insertDirectoryForFile(relativePath); insertDirectoryForFile(relativePath);
pendingInserts++; pendingInserts++;
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}, onFileInserted); // Do not pass `onFileInserted` directly because it gets overwritten below.
// Create a closure capturing `onFileInserted`.
filesystem.insertFile(relativePath, shouldUnpack, { stat: stat }, {}).then(() => onFileInserted(), () => onFileInserted());
}; };
return es.through(function (file) { return es.through(function (file) {

View File

@@ -50,7 +50,7 @@
"rollup-plugin-commonjs": "^10.1.0", "rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-node-resolve": "^5.2.0",
"terser": "4.3.8", "terser": "4.3.8",
"typescript": "^4.0.1-rc", "typescript": "^4.1.0-dev.20200824",
"vsce": "1.48.0", "vsce": "1.48.0",
"vscode-telemetry-extractor": "^1.6.0", "vscode-telemetry-extractor": "^1.6.0",
"xml2js": "^0.4.17" "xml2js": "^0.4.17"

View File

@@ -3544,10 +3544,10 @@ typescript@^3.0.1:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977"
integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
typescript@^4.0.1-rc: typescript@^4.1.0-dev.20200824:
version "4.0.1-rc" version "4.1.0-dev.20200824"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.0.1-rc.tgz#8adc78223eae56fe71d906a5fa90c3543b07a677" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.1.0-dev.20200824.tgz#34c92d9b6e5124600658c0d4e9b8c125beaf577d"
integrity sha512-TCkspT3dSKOykbzS3/WSK7pqU2h1d/lEO6i45Afm5Y3XNAEAo8YXTG3kHOQk/wFq/5uPyO1+X8rb/Q+g7UsxJw== integrity sha512-hTJfocmebnMKoqRw/xs3bL61z87XXtvOUwYtM7zaCX9mAvnfdo1x1bzQlLZAsvdzRIgAHPJQYbqYHKygWkDw6g==
typical@^4.0.0: typical@^4.0.0:
version "4.0.0" version "4.0.0"

View File

@@ -60,12 +60,12 @@
"git": { "git": {
"name": "electron", "name": "electron",
"repositoryUrl": "https://github.com/electron/electron", "repositoryUrl": "https://github.com/electron/electron",
"commitHash": "0c2cb59b6283fe8d6bb4b14f8a832e2166aeaa0c" "commitHash": "03c7a54dc534ce1867d4393b9b1a6989d4a7e005"
} }
}, },
"isOnlyProductionDependency": true, "isOnlyProductionDependency": true,
"license": "MIT", "license": "MIT",
"version": "9.2.0" "version": "9.2.1"
}, },
{ {
"component": { "component": {

View File

@@ -54,7 +54,7 @@
"url": "vscode://schemas/keybindings" "url": "vscode://schemas/keybindings"
}, },
{ {
"fileMatch": "vscode://defaultsettings/defaultSettings.json", "fileMatch": "vscode://defaultsettings/*/*.json",
"url": "vscode://schemas/settings/default" "url": "vscode://schemas/settings/default"
}, },
{ {

View File

@@ -15,7 +15,7 @@
"extensions": [ ".dockerfile", ".containerfile" ], "extensions": [ ".dockerfile", ".containerfile" ],
"filenames": [ "Dockerfile", "Containerfile" ], "filenames": [ "Dockerfile", "Containerfile" ],
"filenamePatterns": [ "Dockerfile.*", "Containerfile.*" ], "filenamePatterns": [ "Dockerfile.*", "Containerfile.*" ],
"aliases": [ "Dockerfile", "Containerfile" ], "aliases": [ "Docker", "Dockerfile", "Containerfile" ],
"configuration": "./language-configuration.json" "configuration": "./language-configuration.json"
}], }],
"grammars": [{ "grammars": [{

View File

@@ -754,13 +754,23 @@
"when": "scmProvider == git" "when": "scmProvider == git"
}, },
{ {
"command": "git.checkout", "command": "git.pull",
"group": "1_header", "group": "1_header@1",
"when": "scmProvider == git"
},
{
"command": "git.push",
"group": "1_header@2",
"when": "scmProvider == git" "when": "scmProvider == git"
}, },
{ {
"command": "git.clone", "command": "git.clone",
"group": "1_header", "group": "1_header@3",
"when": "scmProvider == git"
},
{
"command": "git.checkout",
"group": "1_header@4",
"when": "scmProvider == git" "when": "scmProvider == git"
}, },
{ {
@@ -1915,7 +1925,11 @@
"[git-commit]": { "[git-commit]": {
"editor.rulers": [ "editor.rulers": [
72 72
] ],
"workbench.editor.restoreViewState": false
},
"[git-rebase]": {
"workbench.editor.restoreViewState": false
} }
}, },
"viewsWelcome": [ "viewsWelcome": [

View File

@@ -107,7 +107,7 @@
"config.smartCommitChanges.all": "Automatically stage all changes.", "config.smartCommitChanges.all": "Automatically stage all changes.",
"config.smartCommitChanges.tracked": "Automatically stage tracked changes only.", "config.smartCommitChanges.tracked": "Automatically stage tracked changes only.",
"config.suggestSmartCommit": "Suggests to enable smart commit (commit all changes when there are no staged changes).", "config.suggestSmartCommit": "Suggests to enable smart commit (commit all changes when there are no staged changes).",
"config.enableCommitSigning": "Enables commit signing with GPG.", "config.enableCommitSigning": "Enables commit signing with GPG or X.509.",
"config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.", "config.discardAllScope": "Controls what changes are discarded by the `Discard all changes` command. `all` discards all changes. `tracked` discards only tracked files. `prompt` shows a prompt dialog every time the action is run.",
"config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.", "config.decorations.enabled": "Controls whether Git contributes colors and badges to the explorer and the open editors view.",
"config.enableStatusBarSync": "Controls whether the Git Sync command appears in the status bar.", "config.enableStatusBarSync": "Controls whether the Git Sync command appears in the status bar.",

View File

@@ -460,7 +460,7 @@ export class CommandCenter {
@command('git.clone') @command('git.clone')
async clone(url?: string, parentPath?: string): Promise<void> { async clone(url?: string, parentPath?: string): Promise<void> {
if (!url) { if (!url || typeof url !== 'string') {
url = await pickRemoteSource(this.model, { url = await pickRemoteSource(this.model, {
providerLabel: provider => localize('clonefrom', "Clone from {0}", provider.name), providerLabel: provider => localize('clonefrom', "Clone from {0}", provider.name),
urlLabel: localize('repourl', "Clone from URL") urlLabel: localize('repourl', "Clone from URL")

View File

@@ -232,7 +232,7 @@ export class GitTimelineProvider implements TimelineProvider {
private onRepositoryStatusChanged(_repo: Repository) { private onRepositoryStatusChanged(_repo: Repository) {
// console.log(`GitTimelineProvider.onRepositoryStatusChanged`); // console.log(`GitTimelineProvider.onRepositoryStatusChanged`);
// This is crappy, but for now just save the last time a status was run and use that as the timestamp for staged items // This is less than ideal, but for now just save the last time a status was run and use that as the timestamp for staged items
this.repoStatusDate = new Date(); this.repoStatusDate = new Date();
this.fireChanged(); this.fireChanged();

View File

@@ -11,15 +11,14 @@
"categories": [ "categories": [
"Other" "Other"
], ],
"activationEvents": [
"*",
"onAuthenticationRequest:github"
],
"extensionKind": [ "extensionKind": [
"ui", "ui",
"workspace", "workspace",
"web" "web"
], ],
"activationEvents": [
"onAuthenticationRequest:github"
],
"contributes": { "contributes": {
"commands": [ "commands": [
{ {
@@ -34,7 +33,13 @@
"when": "false" "when": "false"
} }
] ]
} },
"authentication": [
{
"label": "GitHub",
"id": "github"
}
]
}, },
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"main": "./out/extension.js", "main": "./out/extension.js",

View File

@@ -22,7 +22,7 @@ export async function activate(context: vscode.ExtensionContext) {
return loginService.manuallyProvideToken(); return loginService.manuallyProvideToken();
})); }));
vscode.authentication.registerAuthenticationProvider({ context.subscriptions.push(vscode.authentication.registerAuthenticationProvider({
id: 'github', id: 'github',
label: 'GitHub', label: 'GitHub',
supportsMultipleAccounts: false, supportsMultipleAccounts: false,
@@ -70,7 +70,7 @@ export async function activate(context: vscode.ExtensionContext) {
throw e; throw e;
} }
} }
}); }));
return; return;
} }

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ExtensionContext } from 'vscode'; import { ExtensionContext, Uri } from 'vscode';
import { LanguageClientOptions } from 'vscode-languageclient'; import { LanguageClientOptions } from 'vscode-languageclient';
import { startClient, LanguageClientConstructor } from '../jsonClient'; import { startClient, LanguageClientConstructor } from '../jsonClient';
import { LanguageClient } from 'vscode-languageclient/browser'; import { LanguageClient } from 'vscode-languageclient/browser';
@@ -17,9 +17,9 @@ declare function fetch(uri: string, options: any): any;
// this method is called when vs code is activated // this method is called when vs code is activated
export function activate(context: ExtensionContext) { export function activate(context: ExtensionContext) {
const serverMain = context.asAbsolutePath('server/dist/browser/jsonServerMain.js'); const serverMain = Uri.joinPath(context.extensionUri, 'server/dist/browser/jsonServerMain.js');
try { try {
const worker = new Worker(serverMain); const worker = new Worker(serverMain.toString());
const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => { const newLanguageClient: LanguageClientConstructor = (id: string, name: string, clientOptions: LanguageClientOptions) => {
return new LanguageClient(id, name, clientOptions, worker); return new LanguageClient(id, name, clientOptions, worker);
}; };

View File

@@ -14,7 +14,7 @@
"dependencies": { "dependencies": {
"jsonc-parser": "^2.2.1", "jsonc-parser": "^2.2.1",
"request-light": "^0.3.0", "request-light": "^0.3.0",
"vscode-json-languageservice": "^3.8.0", "vscode-json-languageservice": "^3.8.3",
"vscode-languageserver": "7.0.0-next.3", "vscode-languageserver": "7.0.0-next.3",
"vscode-uri": "^2.1.2" "vscode-uri": "^2.1.2"
}, },

View File

@@ -80,10 +80,10 @@ request-light@^0.3.0:
https-proxy-agent "^2.2.4" https-proxy-agent "^2.2.4"
vscode-nls "^4.1.1" vscode-nls "^4.1.1"
vscode-json-languageservice@^3.8.0: vscode-json-languageservice@^3.8.3:
version "3.8.0" version "3.8.3"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.8.0.tgz#c7e7283f993e3db39fa5501407b023ada6fd3ae3" resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.8.3.tgz#fae5e7bdda2b6ec4f64588c571df40b6bfcb09b5"
integrity sha512-sYz5JElJMIlPoqhrRfG3VKnDjnPinLdblIiEVsJgTz1kj2hWD2q5BSbo+evH/5/jKDXDLfA8kb0lHC4vd5g5zg== integrity sha512-8yPag/NQHCuTthahyaTtzK0DHT0FKM/xBU0mFBQ8nMo8C1i2P+FCyIVqICoNoHkRI2BTGlXKomPUpsqjSz0TnQ==
dependencies: dependencies:
jsonc-parser "^2.2.1" jsonc-parser "^2.2.1"
vscode-languageserver-textdocument "^1.0.1" vscode-languageserver-textdocument "^1.0.1"

View File

@@ -12,7 +12,6 @@
], ],
"enableProposedApi": true, "enableProposedApi": true,
"activationEvents": [ "activationEvents": [
"*",
"onAuthenticationRequest:microsoft" "onAuthenticationRequest:microsoft"
], ],
"extensionKind": [ "extensionKind": [
@@ -20,6 +19,14 @@
"workspace", "workspace",
"web" "web"
], ],
"contributes": {
"authentication": [
{
"label": "Microsoft",
"id": "microsoft"
}
]
},
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217", "aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"main": "./out/extension.js", "main": "./out/extension.js",
"browser": "./dist/browser/extension.js", "browser": "./dist/browser/extension.js",

View File

@@ -5,6 +5,7 @@
import * as randomBytes from 'randombytes'; import * as randomBytes from 'randombytes';
import * as querystring from 'querystring'; import * as querystring from 'querystring';
import { Buffer } from 'buffer';
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { createServer, startServer } from './authServer'; import { createServer, startServer } from './authServer';
@@ -528,7 +529,7 @@ export class AzureActiveDirectoryService {
} }
} catch (e) { } catch (e) {
Logger.error('Refreshing token failed'); Logger.error('Refreshing token failed');
throw e; throw new Error(REFRESH_NETWORK_FAILURE);
} }
} }

View File

@@ -42,7 +42,7 @@ export class ResourceTypeService implements IResourceTypeService {
vscode.extensions.all.forEach((extension) => { vscode.extensions.all.forEach((extension) => {
const extensionResourceTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.resourceDeploymentTypes as ResourceType[]; const extensionResourceTypes = extension.packageJSON.contributes && extension.packageJSON.contributes.resourceDeploymentTypes as ResourceType[];
if (extensionResourceTypes) { if (extensionResourceTypes) {
extensionResourceTypes.forEach((resourceType) => { extensionResourceTypes.forEach((resourceType: ResourceType) => {
this.updatePathProperties(resourceType, extension.extensionPath); this.updatePathProperties(resourceType, extension.extensionPath);
resourceType.getProvider = (selectedOptions) => { return this.getProvider(resourceType, selectedOptions); }; resourceType.getProvider = (selectedOptions) => { return this.getProvider(resourceType, selectedOptions); };
this._resourceTypes.push(resourceType); this._resourceTypes.push(resourceType);

View File

@@ -233,6 +233,20 @@
"foreground": "#22aa44" "foreground": "#22aa44"
} }
}, },
{
"name": "Markup: Strong",
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"name": "Markup: Emphasis",
"scope": "markup.italic",
"settings": {
"fontStyle": "italic"
}
},
{ {
"name": "Markup Inline", "name": "Markup Inline",
"scope": "markup.inline.raw", "scope": "markup.inline.raw",
@@ -242,11 +256,14 @@
} }
}, },
{ {
"name": "Markup Setext Header", "name": "Markup Headings",
"scope": "markup.heading.setext", "scope": [
"markup.heading",
"markup.heading.setext"
],
"settings": { "settings": {
"fontStyle": "", "fontStyle": "bold",
"foreground": "#ddbb88" "foreground": "#6688cc"
} }
} }
], ],

View File

@@ -136,6 +136,7 @@
{ {
"scope": "markup.heading", "scope": "markup.heading",
"settings": { "settings": {
"fontStyle": "bold",
"foreground": "#6796e6" "foreground": "#6796e6"
} }
}, },

View File

@@ -260,7 +260,7 @@
"entity.name.section" "entity.name.section"
], ],
"settings": { "settings": {
"fontStyle": "", "fontStyle": "bold",
"foreground": "#8ab1b0" "foreground": "#8ab1b0"
} }
}, },

View File

@@ -350,6 +350,20 @@
"foreground": "#fb9a4bff" "foreground": "#fb9a4bff"
} }
}, },
{
"name": "Markup: Strong",
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"name": "Markup: Emphasis",
"scope": "markup.italic",
"settings": {
"fontStyle": "italic"
}
},
{ {
"name": "Markup Inline", "name": "Markup Inline",
"scope": "markup.inline.raw", "scope": "markup.inline.raw",
@@ -359,17 +373,15 @@
} }
}, },
{ {
"name": "Markup Headings", "name": "Headings",
"scope": "markup.heading", "scope": [
"markup.heading",
"markup.heading.setext",
"punctuation.definition.heading",
"entity.name.section"
],
"settings": { "settings": {
"foreground": "#fec758ff" "fontStyle": "bold",
}
},
{
"name": "Markup Setext Header",
"scope": "markup.heading.setext",
"settings": {
"fontStyle": "",
"foreground": "#fec758ff" "foreground": "#fec758ff"
} }
}, },

View File

@@ -305,7 +305,7 @@ exports.update = function () {
} }
return download(fileAssociationFile).then(function (content) { return download(fileAssociationFile).then(function (content) {
let regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g; let regex2 = /\.icon-(?:set|partial)\(['"]([\w-\.+]+)['"],\s*['"]([\w-]+)['"],\s*(@[\w-]+)\)/g;
while ((match = regex2.exec(content)) !== null) { while ((match = regex2.exec(content)) !== null) {
let pattern = match[1]; let pattern = match[1];
let def = '_' + match[2]; let def = '_' + match[2];

View File

@@ -6,7 +6,7 @@
"git": { "git": {
"name": "seti-ui", "name": "seti-ui",
"repositoryUrl": "https://github.com/jesseweed/seti-ui", "repositoryUrl": "https://github.com/jesseweed/seti-ui",
"commitHash": "f3b2775662b0075aab56e5f0c03269f21f3f0f30" "commitHash": "719e5d384e878b0e190abc80247a8726f083a393"
} }
}, },
"version": "0.1.0" "version": "0.1.0"

File diff suppressed because it is too large Load Diff

View File

@@ -270,6 +270,20 @@
"foreground": "#D33682" "foreground": "#D33682"
} }
}, },
{
"name": "Markup: Strong",
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"name": "Markup: Emphasis",
"scope": "markup.italic",
"settings": {
"fontStyle": "italic"
}
},
{ {
"name": "Markup Inline", "name": "Markup Inline",
"scope": "markup.inline.raw", "scope": "markup.inline.raw",
@@ -282,6 +296,7 @@
"name": "Markup Headings", "name": "Markup Headings",
"scope": "markup.heading", "scope": "markup.heading",
"settings": { "settings": {
"fontStyle": "bold",
"foreground": "#268BD2" "foreground": "#268BD2"
} }
}, },

View File

@@ -273,6 +273,20 @@
"foreground": "#D33682" "foreground": "#D33682"
} }
}, },
{
"name": "Markup: Strong",
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"name": "Markup: Emphasis",
"scope": "markup.italic",
"settings": {
"fontStyle": "italic"
}
},
{ {
"name": "Markup Inline", "name": "Markup Inline",
"scope": "markup.inline.raw", "scope": "markup.inline.raw",
@@ -285,6 +299,7 @@
"name": "Markup Headings", "name": "Markup Headings",
"scope": "markup.heading", "scope": "markup.heading",
"settings": { "settings": {
"fontStyle": "bold",
"foreground": "#268BD2" "foreground": "#268BD2"
} }
}, },

View File

@@ -223,6 +223,20 @@
"foreground": "#FFC58F" "foreground": "#FFC58F"
} }
}, },
{
"name": "Markup: Strong",
"scope": "markup.bold",
"settings": {
"fontStyle": "bold"
}
},
{
"name": "Markup: Emphasis",
"scope": "markup.italic",
"settings": {
"fontStyle": "italic"
}
},
{ {
"name": "Markup Inline", "name": "Markup Inline",
"scope": "markup.inline.raw", "scope": "markup.inline.raw",
@@ -231,6 +245,13 @@
"foreground": "#FF9DA4" "foreground": "#FF9DA4"
} }
}, },
{
"name": "Markup Headings",
"scope": "markup.heading",
"settings": {
"fontStyle": "bold"
}
},
{ {
"scope": "token.info-token", "scope": "token.info-token",
"settings": { "settings": {

View File

@@ -40,6 +40,7 @@
"strict-vscode": "node --max_old_space_size=4095 node_modules/typescript/bin/tsc -p src/tsconfig.vscode.json", "strict-vscode": "node --max_old_space_size=4095 node_modules/typescript/bin/tsc -p src/tsconfig.vscode.json",
"strict-vscode-watch": "node --max_old_space_size=4095 node_modules/typescript/bin/tsc -p src/tsconfig.vscode.json --watch", "strict-vscode-watch": "node --max_old_space_size=4095 node_modules/typescript/bin/tsc -p src/tsconfig.vscode.json --watch",
"strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization", "strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization",
"tsec-compile-check": "node_modules/tsec/bin/tsec -p src/tsconfig.json --noEmit",
"valid-layers-check": "node build/lib/layersChecker.js", "valid-layers-check": "node build/lib/layersChecker.js",
"strict-function-types-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictFunctionTypes", "strict-function-types-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictFunctionTypes",
"update-distro": "node build/npm/update-distro.js", "update-distro": "node build/npm/update-distro.js",
@@ -73,7 +74,7 @@
"keytar": "^5.5.0", "keytar": "^5.5.0",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"native-is-elevated": "0.4.1", "native-is-elevated": "0.4.1",
"native-keymap": "2.1.2", "native-keymap": "2.2.0",
"native-watchdog": "1.3.0", "native-watchdog": "1.3.0",
"ng2-charts": "^1.6.0", "ng2-charts": "^1.6.0",
"node-pty": "0.10.0-beta8", "node-pty": "0.10.0-beta8",
@@ -128,7 +129,7 @@
"@typescript-eslint/eslint-plugin": "3.2.0", "@typescript-eslint/eslint-plugin": "3.2.0",
"@typescript-eslint/parser": "^3.3.0", "@typescript-eslint/parser": "^3.3.0",
"ansi-colors": "^3.2.3", "ansi-colors": "^3.2.3",
"asar": "^0.14.0", "asar": "^3.0.3",
"chromium-pickle-js": "^0.2.0", "chromium-pickle-js": "^0.2.0",
"concurrently": "^5.2.0", "concurrently": "^5.2.0",
"copy-webpack-plugin": "^4.5.2", "copy-webpack-plugin": "^4.5.2",
@@ -136,7 +137,7 @@
"css-loader": "^3.2.0", "css-loader": "^3.2.0",
"debounce": "^1.0.0", "debounce": "^1.0.0",
"deemon": "^1.4.0", "deemon": "^1.4.0",
"electron": "9.2.0", "electron": "9.2.1",
"eslint": "6.8.0", "eslint": "6.8.0",
"eslint-plugin-jsdoc": "^19.1.0", "eslint-plugin-jsdoc": "^19.1.0",
"event-stream": "3.3.4", "event-stream": "3.3.4",
@@ -193,7 +194,8 @@
"temp-write": "^3.4.0", "temp-write": "^3.4.0",
"ts-loader": "^4.4.2", "ts-loader": "^4.4.2",
"typemoq": "^0.3.2", "typemoq": "^0.3.2",
"typescript": "^4.0.1-rc", "tsec": "googleinterns/tsec",
"typescript": "^4.1.0-dev.20200824",
"typescript-formatter": "7.1.0", "typescript-formatter": "7.1.0",
"underscore": "^1.8.2", "underscore": "^1.8.2",
"vinyl": "^2.0.0", "vinyl": "^2.0.0",

View File

@@ -18,6 +18,7 @@ const fancyLog = require('fancy-log');
const ansiColors = require('ansi-colors'); const ansiColors = require('ansi-colors');
const remote = require('gulp-remote-retry-src'); const remote = require('gulp-remote-retry-src');
const vfs = require('vinyl-fs'); const vfs = require('vinyl-fs');
const uuid = require('uuid');
const extensions = require('../../build/lib/extensions'); const extensions = require('../../build/lib/extensions');
@@ -27,21 +28,23 @@ const BUILTIN_MARKETPLACE_EXTENSIONS_ROOT = path.join(APP_ROOT, '.build', 'built
const WEB_DEV_EXTENSIONS_ROOT = path.join(APP_ROOT, '.build', 'builtInWebDevExtensions'); const WEB_DEV_EXTENSIONS_ROOT = path.join(APP_ROOT, '.build', 'builtInWebDevExtensions');
const WEB_MAIN = path.join(APP_ROOT, 'src', 'vs', 'code', 'browser', 'workbench', 'workbench-dev.html'); const WEB_MAIN = path.join(APP_ROOT, 'src', 'vs', 'code', 'browser', 'workbench', 'workbench-dev.html');
const WEB_PLAYGROUND_VERSION = '0.0.2'; const WEB_PLAYGROUND_VERSION = '0.0.8';
const args = minimist(process.argv, { const args = minimist(process.argv, {
boolean: [ boolean: [
'no-launch', 'no-launch',
'help', 'help',
'verbose', 'verbose',
'wrap-iframe' 'wrap-iframe',
'enable-sync'
], ],
string: [ string: [
'scheme', 'scheme',
'host', 'host',
'port', 'port',
'local_port', 'local_port',
'extension' 'extension',
'github-auth'
], ],
}); });
@@ -50,11 +53,13 @@ if (args.help) {
'yarn web [options]\n' + 'yarn web [options]\n' +
' --no-launch Do not open VSCode web in the browser\n' + ' --no-launch Do not open VSCode web in the browser\n' +
' --wrap-iframe Wrap the Web Worker Extension Host in an iframe\n' + ' --wrap-iframe Wrap the Web Worker Extension Host in an iframe\n' +
' --enable-sync Enable sync by default\n' +
' --scheme Protocol (https or http)\n' + ' --scheme Protocol (https or http)\n' +
' --host Remote host\n' + ' --host Remote host\n' +
' --port Remote/Local port\n' + ' --port Remote/Local port\n' +
' --local_port Local port override\n' + ' --local_port Local port override\n' +
' --extension Path of an extension to include\n' + ' --extension Path of an extension to include\n' +
' --github-auth Github authentication token\n' +
' --verbose Print out more information\n' + ' --verbose Print out more information\n' +
' --help\n' + ' --help\n' +
'[Example]\n' + '[Example]\n' +
@@ -356,14 +361,38 @@ async function handleRoot(req, res) {
const webConfigJSON = { const webConfigJSON = {
folderUri: folderUri, folderUri: folderUri,
staticExtensions, staticExtensions,
enableSyncByDefault: args['enable-sync'],
}; };
if (args['wrap-iframe']) { if (args['wrap-iframe']) {
webConfigJSON._wrapWebWorkerExtHostInIframe = true; webConfigJSON._wrapWebWorkerExtHostInIframe = true;
} }
const credentials = [];
if (args['github-auth']) {
const sessionId = uuid.v4();
credentials.push({
service: 'code-oss.login',
account: 'account',
password: JSON.stringify({
id: sessionId,
providerId: 'github',
accessToken: args['github-auth']
})
}, {
service: 'code-oss-github.login',
account: 'account',
password: JSON.stringify([{
id: sessionId,
scopes: ['user:email'],
accessToken: args['github-auth']
}])
});
}
const data = (await readFile(WEB_MAIN)).toString() const data = (await readFile(WEB_MAIN)).toString()
.replace('{{WORKBENCH_WEB_CONFIGURATION}}', () => escapeAttribute(JSON.stringify(webConfigJSON))) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied .replace('{{WORKBENCH_WEB_CONFIGURATION}}', () => escapeAttribute(JSON.stringify(webConfigJSON))) // use a replace function to avoid that regexp replace patterns ($&, $0, ...) are applied
.replace('{{WORKBENCH_BUILTIN_EXTENSIONS}}', () => escapeAttribute(JSON.stringify(dedupedBuiltInExtensions))) .replace('{{WORKBENCH_BUILTIN_EXTENSIONS}}', () => escapeAttribute(JSON.stringify(dedupedBuiltInExtensions)))
.replace('{{WORKBENCH_CREDENTIALS}}', () => escapeAttribute(JSON.stringify(credentials)))
.replace('{{WEBVIEW_ENDPOINT}}', '') .replace('{{WEBVIEW_ENDPOINT}}', '')
.replace('{{REMOTE_USER_DATA_URI}}', ''); .replace('{{REMOTE_USER_DATA_URI}}', '');

View File

@@ -16,6 +16,7 @@ exports.base = [{
}]; }];
exports.workerExtensionHost = [entrypoint('vs/workbench/services/extensions/worker/extensionHostWorker')]; exports.workerExtensionHost = [entrypoint('vs/workbench/services/extensions/worker/extensionHostWorker')];
exports.workerNotebook = [entrypoint('vs/workbench/contrib/notebook/common/services/notebookSimpleWorker')];
exports.workbenchDesktop = require('./vs/workbench/buildfile.desktop').collectModules(); exports.workbenchDesktop = require('./vs/workbench/buildfile.desktop').collectModules();
exports.workbenchWeb = require('./vs/workbench/buildfile.web').collectModules(); exports.workbenchWeb = require('./vs/workbench/buildfile.web').collectModules();

View File

@@ -92,7 +92,7 @@ export default class DiffEditorComponent extends ComponentBase implements ICompo
let editorinput1 = this._instantiationService.createInstance(ResourceEditorInput, uri1, 'source', undefined, undefined); let editorinput1 = this._instantiationService.createInstance(ResourceEditorInput, uri1, 'source', undefined, undefined);
let editorinput2 = this._instantiationService.createInstance(ResourceEditorInput, uri2, 'target', undefined, undefined); let editorinput2 = this._instantiationService.createInstance(ResourceEditorInput, uri2, 'target', undefined, undefined);
this._editorInput = new DiffEditorInput('DiffEditor', undefined, editorinput1, editorinput2, true); this._editorInput = new DiffEditorInput('DiffEditor', undefined, editorinput1, editorinput2, true);
this._editor.setInput(this._editorInput, undefined, cancellationTokenSource.token); this._editor.setInput(this._editorInput, undefined, undefined, cancellationTokenSource.token);
this._editorInput.resolve().then(model => { this._editorInput.resolve().then(model => {

View File

@@ -70,7 +70,7 @@ export default class EditorComponent extends ComponentBase implements IComponent
this._editor.setVisible(true); this._editor.setVisible(true);
let uri = this.createUri(); let uri = this.createUri();
this._editorInput = this.editorService.createEditorInput({ forceUntitled: true, resource: uri, mode: 'plaintext' }) as UntitledTextEditorInput; this._editorInput = this.editorService.createEditorInput({ forceUntitled: true, resource: uri, mode: 'plaintext' }) as UntitledTextEditorInput;
await this._editor.setInput(this._editorInput, undefined); await this._editor.setInput(this._editorInput, undefined, undefined);
const model = await this._editorInput.resolve(); const model = await this._editorInput.resolve();
this._editorModel = model.textEditorModel; this._editorModel = model.textEditorModel;
this.fireEvent({ this.fireEvent({

View File

@@ -6,15 +6,15 @@ import 'vs/css!./media/modelViewEditor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { ModelViewInput } from 'sql/workbench/browser/modelComponents/modelViewInput'; import { ModelViewInput } from 'sql/workbench/browser/modelComponents/modelViewInput';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
export class ModelViewEditor extends BaseEditor { export class ModelViewEditor extends EditorPane {
public static ID: string = 'workbench.editor.modelViewEditor'; public static ID: string = 'workbench.editor.modelViewEditor';
@@ -62,7 +62,7 @@ export class ModelViewEditor extends BaseEditor {
} }
} }
async setInput(input: ModelViewInput, options?: EditorOptions): Promise<void> { async setInput(input: ModelViewInput, options?: EditorOptions, context?: IEditorOpenContext): Promise<void> {
if (this.input && this.input.matches(input)) { if (this.input && this.input.matches(input)) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
@@ -73,7 +73,7 @@ export class ModelViewEditor extends BaseEditor {
input.container.style.visibility = 'visible'; input.container.style.visibility = 'visible';
this._content.setAttribute('aria-flowto', input.container.id); this._content.setAttribute('aria-flowto', input.container.id);
await super.setInput(input, options, CancellationToken.None); await super.setInput(input, options, context, CancellationToken.None);
this.doUpdateContainer(); this.doUpdateContainer();
} }

View File

@@ -15,7 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -85,8 +85,8 @@ export class QueryTextEditor extends BaseTextEditor {
return options; return options;
} }
setInput(input: UntitledTextEditorInput, options: EditorOptions): Promise<void> { setInput(input: UntitledTextEditorInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
return super.setInput(input, options, CancellationToken.None) return super.setInput(input, options, context, CancellationToken.None)
.then(() => this.input.resolve() .then(() => this.input.resolve()
.then(editorModel => editorModel.load()) .then(editorModel => editorModel.load())
.then(editorModel => this.getControl().setModel((<ResourceEditorModel>editorModel).textEditorModel))); .then(editorModel => this.getControl().setModel((<ResourceEditorModel>editorModel).textEditorModel)));

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -25,7 +25,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { IQueryManagementService } from 'sql/workbench/services/query/common/queryManagement'; import { IQueryManagementService } from 'sql/workbench/services/query/common/queryManagement';
export class DashboardEditor extends BaseEditor { export class DashboardEditor extends EditorPane {
public static ID: string = 'workbench.editor.connectiondashboard'; public static ID: string = 'workbench.editor.connectiondashboard';
private _dashboardContainer: HTMLElement; private _dashboardContainer: HTMLElement;
@@ -77,14 +77,14 @@ export class DashboardEditor extends BaseEditor {
this._dashboardService.layout(dimension); this._dashboardService.layout(dimension);
} }
public async setInput(input: DashboardInput, options: EditorOptions): Promise<void> { public async setInput(input: DashboardInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
if (this.input && this.input.matches(input)) { if (this.input && this.input.matches(input)) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
const parentElement = this.getContainer(); const parentElement = this.getContainer();
super.setInput(input, options, CancellationToken.None); super.setInput(input, options, context, CancellationToken.None);
DOM.clearNode(parentElement); DOM.clearNode(parentElement);

View File

@@ -7,8 +7,8 @@ import * as strings from 'vs/base/common/strings';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { EditorOptions, EditorInput, IEditorControl, IEditorPane } from 'vs/workbench/common/editor'; import { EditorOptions, EditorInput, IEditorControl, IEditorPane, IEditorOpenContext } from 'vs/workbench/common/editor';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -41,7 +41,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
/** /**
* Editor that hosts an action bar and a resultSetInput for an edit data session * Editor that hosts an action bar and a resultSetInput for an edit data session
*/ */
export class EditDataEditor extends BaseEditor { export class EditDataEditor extends EditorPane {
public static ID: string = 'workbench.editor.editDataEditor'; public static ID: string = 'workbench.editor.editDataEditor';
@@ -213,7 +213,7 @@ export class EditDataEditor extends BaseEditor {
/** /**
* Sets the input data for this editor. * Sets the input data for this editor.
*/ */
public setInput(newInput: EditDataInput, options?: EditorOptions): Promise<void> { public setInput(newInput: EditDataInput, options?: EditorOptions, context?: IEditorOpenContext): Promise<void> {
let oldInput = <EditDataInput>this.input; let oldInput = <EditDataInput>this.input;
if (!newInput.setup) { if (!newInput.setup) {
this._initialized = false; this._initialized = false;
@@ -224,7 +224,7 @@ export class EditDataEditor extends BaseEditor {
newInput.setupComplete(); newInput.setupComplete();
} }
return super.setInput(newInput, options, CancellationToken.None) return super.setInput(newInput, options, context, CancellationToken.None)
.then(() => this._updateInput(oldInput, newInput, options)); .then(() => this._updateInput(oldInput, newInput, options));
} }
@@ -251,7 +251,7 @@ export class EditDataEditor extends BaseEditor {
} }
// PRIVATE METHODS //////////////////////////////////////////////////////////// // PRIVATE METHODS ////////////////////////////////////////////////////////////
private _createEditor(editorInput: EditorInput, container: HTMLElement): Promise<BaseEditor> { private _createEditor(editorInput: EditorInput, container: HTMLElement): Promise<EditorPane> {
const descriptor = this._editorDescriptorService.getEditor(editorInput); const descriptor = this._editorDescriptorService.getEditor(editorInput);
if (!descriptor) { if (!descriptor) {
return Promise.reject(new Error(strings.format('Can not find a registered editor for the input {0}', editorInput))); return Promise.reject(new Error(strings.format('Can not find a registered editor for the input {0}', editorInput)));
@@ -493,7 +493,7 @@ export class EditDataEditor extends BaseEditor {
*/ */
private _onResultsEditorCreated(resultsEditor: EditDataResultsEditor, resultsInput: EditDataResultsInput, options: EditorOptions): Promise<void> { private _onResultsEditorCreated(resultsEditor: EditDataResultsEditor, resultsInput: EditDataResultsInput, options: EditorOptions): Promise<void> {
this._resultsEditor = resultsEditor; this._resultsEditor = resultsEditor;
return this._resultsEditor.setInput(resultsInput, options); return this._resultsEditor.setInput(resultsInput, options, undefined);
} }
/** /**
@@ -501,7 +501,7 @@ export class EditDataEditor extends BaseEditor {
*/ */
private _onSqlEditorCreated(sqlEditor: TextResourceEditor, sqlInput: UntitledTextEditorInput, options: EditorOptions): Thenable<void> { private _onSqlEditorCreated(sqlEditor: TextResourceEditor, sqlInput: UntitledTextEditorInput, options: EditorOptions): Thenable<void> {
this._sqlEditor = sqlEditor; this._sqlEditor = sqlEditor;
return this._sqlEditor.setInput(sqlInput, options, CancellationToken.None); return this._sqlEditor.setInput(sqlInput, options, undefined, CancellationToken.None);
} }
private _resizeGridContents(): void { private _resizeGridContents(): void {

View File

@@ -5,13 +5,13 @@
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { getZoomLevel } from 'vs/base/browser/browser'; import { getZoomLevel } from 'vs/base/browser/browser';
import { Configuration } from 'vs/editor/browser/config/configuration'; import { Configuration } from 'vs/editor/browser/config/configuration';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import * as types from 'vs/base/common/types'; import * as types from 'vs/base/common/types';
import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel'; import { IQueryModelService } from 'sql/workbench/services/query/common/queryModel';
@@ -21,7 +21,7 @@ import { EditDataResultsInput } from 'sql/workbench/browser/editData/editDataRes
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
export class EditDataResultsEditor extends BaseEditor { export class EditDataResultsEditor extends EditorPane {
public static ID: string = 'workbench.editor.editDataResultsEditor'; public static ID: string = 'workbench.editor.editDataResultsEditor';
protected _input: EditDataResultsInput; protected _input: EditDataResultsInput;
@@ -63,8 +63,8 @@ export class EditDataResultsEditor extends BaseEditor {
public layout(dimension: DOM.Dimension): void { public layout(dimension: DOM.Dimension): void {
} }
public setInput(input: EditDataResultsInput, options: EditorOptions): Promise<void> { public setInput(input: EditDataResultsInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
super.setInput(input, options, CancellationToken.None); super.setInput(input, options, context, CancellationToken.None);
this._applySettings(); this._applySettings();
if (!input.hasBootstrapped) { if (!input.hasBootstrapped) {
this.createGridPanel(); this.createGridPanel();

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations'; import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
@@ -19,6 +19,7 @@ import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
import { InstallRecommendedExtensionsByScenarioAction, ShowRecommendedExtensionsByScenarioAction } from 'sql/workbench/contrib/extensions/browser/extensionsActions'; import { InstallRecommendedExtensionsByScenarioAction, ShowRecommendedExtensionsByScenarioAction } from 'sql/workbench/contrib/extensions/browser/extensionsActions';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys'; import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
const choiceNever = localize('neverShowAgain', "Don't Show Again"); const choiceNever = localize('neverShowAgain', "Don't Show Again");
@@ -28,18 +29,20 @@ export class ScenarioRecommendations extends ExtensionRecommendations {
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; } get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
constructor( constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean, promptedExtensionRecommendations: PromptedExtensionRecommendations,
@IProductService private readonly productService: IProductService, @IProductService private readonly productService: IProductService,
@IInstantiationService instantiationService: IInstantiationService, @IInstantiationService private readonly instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService, @IConfigurationService configurationService: IConfigurationService,
@INotificationService notificationService: INotificationService, @INotificationService private readonly notificationService: INotificationService,
@ITelemetryService telemetryService: ITelemetryService, @ITelemetryService telemetryService: ITelemetryService,
@IStorageService storageService: IStorageService, @IStorageService private readonly storageService: IStorageService,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService, @IExtensionManagementService protected readonly extensionManagementService: IExtensionManagementService,
@IAdsTelemetryService private readonly adsTelemetryService: IAdsTelemetryService, @IAdsTelemetryService private readonly adsTelemetryService: IAdsTelemetryService,
@IExtensionsWorkbenchService protected readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService @IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
) { ) {
super(isExtensionAllowedToBeRecommended, instantiationService, configurationService, notificationService, telemetryService, storageService, storageKeysSyncRegistryService); super(promptedExtensionRecommendations);
// this._recommendations = productService.recommendedExtensionsByScenario.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' })); // this._recommendations = productService.recommendedExtensionsByScenario.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' }));
} }
@@ -123,12 +126,11 @@ export class ScenarioRecommendations extends ExtensionRecommendations {
}); });
} }
getRecommendedExtensionsByScenario(scenarioType: string): Promise<IExtensionRecommendation[]> { async getRecommendedExtensionsByScenario(scenarioType: string): Promise<IExtensionRecommendation[]> {
if (!scenarioType) { if (!scenarioType) {
return Promise.reject(new Error(localize('scenarioTypeUndefined', 'The scenario type for extension recommendations must be provided.'))); return Promise.reject(new Error(localize('scenarioTypeUndefined', 'The scenario type for extension recommendations must be provided.')));
} }
return Promise.resolve((this.productService.recommendedExtensionsByScenario[scenarioType] || []) return this.promptedExtensionRecommendations.filterIgnoredOrNotAllowed(this.productService.recommendedExtensionsByScenario[scenarioType] || [])
.filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId)) .map(extensionId => (<IExtensionRecommendation>{ extensionId, sources: ['application'] }));
.map(extensionId => (<IExtensionRecommendation>{ extensionId, sources: ['application'] })));
} }
} }

View File

@@ -3,16 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ExtensionRecommendations, ExtensionRecommendation } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations'; import { ExtensionRecommendations, ExtensionRecommendation, PromptedExtensionRecommendations } from 'vs/workbench/contrib/extensions/browser/extensionRecommendations';
import { IProductService } from 'vs/platform/product/common/productService'; import { IProductService } from 'vs/platform/product/common/productService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
export class StaticRecommendations extends ExtensionRecommendations { export class StaticRecommendations extends ExtensionRecommendations {
@@ -20,16 +14,10 @@ export class StaticRecommendations extends ExtensionRecommendations {
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; } get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
constructor( constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean, promptedExtensionRecommendations: PromptedExtensionRecommendations,
@IProductService productService: IProductService, @IProductService productService: IProductService
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService,
@INotificationService notificationService: INotificationService,
@ITelemetryService telemetryService: ITelemetryService,
@IStorageService storageService: IStorageService,
@IStorageKeysSyncRegistryService storageKeysSyncRegistryService: IStorageKeysSyncRegistryService
) { ) {
super(isExtensionAllowedToBeRecommended, instantiationService, configurationService, notificationService, telemetryService, storageService, storageKeysSyncRegistryService); super(promptedExtensionRecommendations);
this._recommendations = productService.recommendedExtensions.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' })); this._recommendations = productService.recommendedExtensions.map(r => ({ extensionId: r, reason: { reasonId: ExtensionRecommendationReason.Application, reasonText: localize('defaultRecommendations', "This extension is recommended by Azure Data Studio.") }, source: 'application' }));
} }

View File

@@ -203,7 +203,7 @@ export class CodeComponent extends CellView implements OnInit, OnChanges {
cellModelSource = Array.isArray(this.cellModel.source) ? this.cellModel.source.join('') : this.cellModel.source; cellModelSource = Array.isArray(this.cellModel.source) ? this.cellModel.source.join('') : this.cellModel.source;
const model = this._instantiationService.createInstance(UntitledTextEditorModel, uri, false, cellModelSource, this.cellModel.language, undefined); const model = this._instantiationService.createInstance(UntitledTextEditorModel, uri, false, cellModelSource, this.cellModel.language, undefined);
this._editorInput = this._instantiationService.createInstance(UntitledTextEditorInput, model); this._editorInput = this._instantiationService.createInstance(UntitledTextEditorInput, model);
await this._editor.setInput(this._editorInput, undefined); await this._editor.setInput(this._editorInput, undefined, undefined);
this.setFocusAndScroll(); this.setFocusAndScroll();
let untitledEditorModel = await this._editorInput.resolve() as UntitledTextEditorModel; let untitledEditorModel = await this._editorInput.resolve() as UntitledTextEditorModel;

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { bootstrapAngular } from 'sql/workbench/services/bootstrap/browser/bootstrapService'; import { bootstrapAngular } from 'sql/workbench/services/bootstrap/browser/bootstrapService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -35,7 +35,7 @@ import { TimeoutTimer } from 'vs/base/common/async';
import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor'; import { BaseTextEditor } from 'vs/workbench/browser/parts/editor/textEditor';
import { onUnexpectedError } from 'vs/base/common/errors'; import { onUnexpectedError } from 'vs/base/common/errors';
export class NotebookEditor extends BaseEditor implements IFindNotebookController { export class NotebookEditor extends EditorPane implements IFindNotebookController {
public static ID: string = 'workbench.editor.notebookEditor'; public static ID: string = 'workbench.editor.notebookEditor';
private _notebookContainer: HTMLElement; private _notebookContainer: HTMLElement;
@@ -187,14 +187,14 @@ export class NotebookEditor extends BaseEditor implements IFindNotebookControlle
} }
} }
public async setInput(input: NotebookInput, options: EditorOptions): Promise<void> { public async setInput(input: NotebookInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
if (this.input && this.input.matches(input)) { if (this.input && this.input.matches(input)) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
const parentElement = this.getContainer(); const parentElement = this.getContainer();
await super.setInput(input, options, CancellationToken.None); await super.setInput(input, options, context, CancellationToken.None);
DOM.clearNode(parentElement); DOM.clearNode(parentElement);
await this.setFindInput(parentElement); await this.setFindInput(parentElement);
if (!input.hasBootstrapped) { if (!input.hasBootstrapped) {

View File

@@ -126,7 +126,7 @@ suite.skip('Test class NotebookEditor:', () => {
const testNotebookEditor = new NotebookEditorStub({ cellGuid: cellTextEditorGuid, editor: queryTextEditor, model: notebookModel, notebookParams: <INotebookParams>{ notebookUri: untitledNotebookInput.notebookUri } }); const testNotebookEditor = new NotebookEditorStub({ cellGuid: cellTextEditorGuid, editor: queryTextEditor, model: notebookModel, notebookParams: <INotebookParams>{ notebookUri: untitledNotebookInput.notebookUri } });
notebookService.addNotebookEditor(testNotebookEditor); notebookService.addNotebookEditor(testNotebookEditor);
notebookEditor.clearInput(); notebookEditor.clearInput();
await notebookEditor.setInput(untitledNotebookInput, EditorOptions.create({ pinned: true })); await notebookEditor.setInput(untitledNotebookInput, EditorOptions.create({ pinned: true }), undefined);
untitledNotebookInput.notebookFindModel.notebookModel = undefined; // clear preexisting notebookModel untitledNotebookInput.notebookFindModel.notebookModel = undefined; // clear preexisting notebookModel
const result = await notebookEditor.getNotebookModel(); const result = await notebookEditor.getNotebookModel();
assert.strictEqual(result, notebookModel, `getNotebookModel() should return the model set in the INotebookEditor object`); assert.strictEqual(result, notebookModel, `getNotebookModel() should return the model set in the INotebookEditor object`);
@@ -214,7 +214,7 @@ suite.skip('Test class NotebookEditor:', () => {
untitledNotebookInput /* set to a known input */, untitledNotebookInput /* set to a known input */,
untitledNotebookInput /* tries to set the same input that was previously set */ untitledNotebookInput /* tries to set the same input that was previously set */
]) { ]) {
await notebookEditor.setInput(input, editorOptions); await notebookEditor.setInput(input, editorOptions, undefined);
assert.strictEqual(notebookEditor.input, input, `notebookEditor.input should be the one that we set`); assert.strictEqual(notebookEditor.input, input, `notebookEditor.input should be the one that we set`);
} }
}); });
@@ -225,7 +225,7 @@ suite.skip('Test class NotebookEditor:', () => {
for (const isRevealed of [true, false]) { for (const isRevealed of [true, false]) {
notebookEditor['_findState']['_isRevealed'] = isRevealed; notebookEditor['_findState']['_isRevealed'] = isRevealed;
notebookEditor.clearInput(); notebookEditor.clearInput();
await notebookEditor.setInput(untitledNotebookInput, editorOptions); await notebookEditor.setInput(untitledNotebookInput, editorOptions, undefined);
assert.strictEqual(notebookEditor.input, untitledNotebookInput, `notebookEditor.input should be the one that we set`); assert.strictEqual(notebookEditor.input, untitledNotebookInput, `notebookEditor.input should be the one that we set`);
} }
}); });
@@ -744,7 +744,7 @@ async function setupNotebookEditor(notebookEditor: NotebookEditor, untitledNoteb
async function setInputDocument(notebookEditor: NotebookEditor, untitledNotebookInput: UntitledNotebookInput): Promise<void> { async function setInputDocument(notebookEditor: NotebookEditor, untitledNotebookInput: UntitledNotebookInput): Promise<void> {
const editorOptions = EditorOptions.create({ pinned: true }); const editorOptions = EditorOptions.create({ pinned: true });
await notebookEditor.setInput(untitledNotebookInput, editorOptions); await notebookEditor.setInput(untitledNotebookInput, editorOptions, undefined);
assert.strictEqual(notebookEditor.options, editorOptions, 'NotebookEditor options must be the ones that we set'); assert.strictEqual(notebookEditor.options, editorOptions, 'NotebookEditor options must be the ones that we set');
} }

View File

@@ -38,7 +38,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { IView, SplitView, Sizing } from 'vs/base/browser/ui/splitview/splitview'; import { IView, SplitView, Sizing } from 'vs/base/browser/ui/splitview/splitview';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkbenchThemeService, VS_DARK_THEME, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService, VS_DARK_THEME, VS_HC_THEME } from 'vs/workbench/services/themes/common/workbenchThemeService';
@@ -117,7 +117,7 @@ export interface IDetailData {
value: string; value: string;
} }
export class ProfilerEditor extends BaseEditor { export class ProfilerEditor extends EditorPane {
public static readonly ID: string = 'workbench.editor.profiler'; public static readonly ID: string = 'workbench.editor.profiler';
private _untitledTextEditorModel: UntitledTextEditorModel; private _untitledTextEditorModel: UntitledTextEditorModel;
@@ -440,7 +440,7 @@ export class ProfilerEditor extends BaseEditor {
this._editor.setVisible(true); this._editor.setVisible(true);
this._untitledTextEditorModel = this._instantiationService.createInstance(UntitledTextEditorModel, URI.from({ scheme: Schemas.untitled }), false, undefined, 'sql', undefined); this._untitledTextEditorModel = this._instantiationService.createInstance(UntitledTextEditorModel, URI.from({ scheme: Schemas.untitled }), false, undefined, 'sql', undefined);
this._editorInput = this._instantiationService.createInstance(UntitledTextEditorInput, this._untitledTextEditorModel); this._editorInput = this._instantiationService.createInstance(UntitledTextEditorInput, this._untitledTextEditorModel);
this._editor.setInput(this._editorInput, undefined); this._editor.setInput(this._editorInput, undefined, undefined);
this._editorInput.resolve().then(model => this._editorModel = model.textEditorModel); this._editorInput.resolve().then(model => this._editorModel = model.textEditorModel);
return editorContainer; return editorContainer;
} }
@@ -460,7 +460,7 @@ export class ProfilerEditor extends BaseEditor {
return Promise.resolve(null); return Promise.resolve(null);
} }
return super.setInput(input, options, CancellationToken.None).then(() => { return super.setInput(input, options, undefined, CancellationToken.None).then(() => {
this._profilerTableEditor.setInput(input); this._profilerTableEditor.setInput(input);
if (input.viewTemplate) { if (input.viewTemplate) {

View File

@@ -15,7 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService'; import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
@@ -75,8 +75,8 @@ export class ProfilerResourceEditor extends BaseTextEditor {
return options; return options;
} }
setInput(input: UntitledTextEditorInput, options: EditorOptions): Promise<void> { setInput(input: UntitledTextEditorInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
return super.setInput(input, options, CancellationToken.None) return super.setInput(input, options, context, CancellationToken.None)
.then(() => this.input.resolve() .then(() => this.input.resolve()
.then(editorModel => editorModel.load()) .then(editorModel => editorModel.load())
.then(editorModel => this.getControl().setModel((<ResourceEditorModel>editorModel).textEditorModel))); .then(editorModel => this.getControl().setModel((<ResourceEditorModel>editorModel).textEditorModel)));

View File

@@ -20,7 +20,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IEditorAction } from 'vs/editor/common/editorCommon'; import { IEditorAction } from 'vs/editor/common/editorCommon';
import { IOverlayWidget } from 'vs/editor/browser/editorBrowser'; import { IOverlayWidget } from 'vs/editor/browser/editorBrowser';
import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState'; import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -39,7 +39,7 @@ export interface ProfilerTableViewState {
scrollLeft: number; scrollLeft: number;
} }
export class ProfilerTableEditor extends BaseEditor implements IProfilerController, ITableController { export class ProfilerTableEditor extends EditorPane implements IProfilerController, ITableController {
public static ID: string = 'workbench.editor.profiler.table'; public static ID: string = 'workbench.editor.profiler.table';
protected _input: ProfilerInput; protected _input: ProfilerInput;

View File

@@ -7,8 +7,8 @@ import 'vs/css!./media/queryEditor';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import * as path from 'vs/base/common/path'; import * as path from 'vs/base/common/path';
import { EditorOptions, IEditorControl, IEditorMemento } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorControl, IEditorMemento, IEditorOpenContext } from 'vs/workbench/common/editor';
import { BaseEditor, EditorMemento } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane, EditorMemento } from 'vs/workbench/browser/parts/editor/editorPane';
import { Orientation } from 'vs/base/browser/ui/sash/sash'; import { Orientation } from 'vs/base/browser/ui/sash/sash';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -50,7 +50,7 @@ interface IQueryEditorViewState {
* Editor that hosts 2 sub-editors: A TextResourceEditor for SQL file editing, and a QueryResultsEditor * Editor that hosts 2 sub-editors: A TextResourceEditor for SQL file editing, and a QueryResultsEditor
* for viewing and editing query results. This editor is based off SideBySideEditor. * for viewing and editing query results. This editor is based off SideBySideEditor.
*/ */
export class QueryEditor extends BaseEditor { export class QueryEditor extends EditorPane {
public static ID: string = 'workbench.editor.queryEditor'; public static ID: string = 'workbench.editor.queryEditor';
@@ -320,7 +320,7 @@ export class QueryEditor extends BaseEditor {
this.taskbar.setContent(content); this.taskbar.setContent(content);
} }
public async setInput(newInput: QueryEditorInput, options: EditorOptions, token: CancellationToken): Promise<void> { public async setInput(newInput: QueryEditorInput, options: EditorOptions, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
const oldInput = this.input; const oldInput = this.input;
if (newInput.matches(oldInput)) { if (newInput.matches(oldInput)) {
@@ -350,9 +350,9 @@ export class QueryEditor extends BaseEditor {
} }
await Promise.all([ await Promise.all([
super.setInput(newInput, options, token), super.setInput(newInput, options, context, token),
this.currentTextEditor.setInput(newInput.text, options, token), this.currentTextEditor.setInput(newInput.text, options, context, token),
this.resultsEditor.setInput(newInput.results, options) this.resultsEditor.setInput(newInput.results, options, context)
]); ]);
this.inputDisposables.clear(); this.inputDisposables.clear();

View File

@@ -3,10 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey'; import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
import { getZoomLevel } from 'vs/base/browser/browser'; import { getZoomLevel } from 'vs/base/browser/browser';
@@ -71,7 +71,7 @@ export function getBareResultsGridInfoStyles(info: BareResultsGridInfo): string
/** /**
* Editor associated with viewing and editing the data of a query results grid. * Editor associated with viewing and editing the data of a query results grid.
*/ */
export class QueryResultsEditor extends BaseEditor { export class QueryResultsEditor extends EditorPane {
public static ID: string = 'workbench.editor.queryResultsEditor'; public static ID: string = 'workbench.editor.queryResultsEditor';
protected _rawOptions: BareResultsGridInfo; protected _rawOptions: BareResultsGridInfo;
@@ -131,8 +131,8 @@ export class QueryResultsEditor extends BaseEditor {
this.resultsView.layout(dimension); this.resultsView.layout(dimension);
} }
setInput(input: QueryResultsInput, options: EditorOptions): Promise<void> { setInput(input: QueryResultsInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
super.setInput(input, options, CancellationToken.None); super.setInput(input, options, context, CancellationToken.None);
this.resultsView.input = input; this.resultsView.input = input;
return Promise.resolve<void>(null); return Promise.resolve<void>(null);
} }

View File

@@ -16,7 +16,7 @@ import { EditorDescriptorService } from 'sql/workbench/services/queryEditor/brow
import * as TypeMoq from 'typemoq'; import * as TypeMoq from 'typemoq';
import * as assert from 'assert'; import * as assert from 'assert';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices'; import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput'; import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
@@ -76,7 +76,7 @@ suite('SQL QueryEditor Tests', () => {
getId: function (): string { return 'id'; }, getId: function (): string { return 'id'; },
getName: function (): string { return 'name'; }, getName: function (): string { return 'name'; },
describes: function (obj: any): boolean { return true; }, describes: function (obj: any): boolean { return true; },
instantiate(instantiationService: IInstantiationService): BaseEditor { return undefined; } instantiate(instantiationService: IInstantiationService): EditorPane { return undefined; }
}; };
editorDescriptorService = TypeMoq.Mock.ofType(EditorDescriptorService, TypeMoq.MockBehavior.Loose); editorDescriptorService = TypeMoq.Mock.ofType(EditorDescriptorService, TypeMoq.MockBehavior.Loose);
editorDescriptorService.setup(x => x.getEditor(TypeMoq.It.isAny())).returns(() => descriptor); editorDescriptorService.setup(x => x.getEditor(TypeMoq.It.isAny())).returns(() => descriptor);

View File

@@ -4,8 +4,8 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { EditorOptions } from 'vs/workbench/common/editor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IThemeService } from 'vs/platform/theme/common/themeService';
import { QueryPlanInput } from 'sql/workbench/contrib/queryPlan/common/queryPlanInput'; import { QueryPlanInput } from 'sql/workbench/contrib/queryPlan/common/queryPlanInput';
@@ -13,7 +13,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import { QueryPlanView } from 'sql/workbench/contrib/queryPlan/browser/queryPlan'; import { QueryPlanView } from 'sql/workbench/contrib/queryPlan/browser/queryPlan';
export class QueryPlanEditor extends BaseEditor { export class QueryPlanEditor extends EditorPane {
public static ID: string = 'workbench.editor.queryplan'; public static ID: string = 'workbench.editor.queryplan';
@@ -60,13 +60,13 @@ export class QueryPlanEditor extends BaseEditor {
this.view.layout(dimension); this.view.layout(dimension);
} }
public async setInput(input: QueryPlanInput, options: EditorOptions): Promise<void> { public async setInput(input: QueryPlanInput, options: EditorOptions, context: IEditorOpenContext): Promise<void> {
if (this.input instanceof QueryPlanInput && this.input.matches(input)) { if (this.input instanceof QueryPlanInput && this.input.matches(input)) {
return Promise.resolve(undefined); return Promise.resolve(undefined);
} }
await input.resolve(); await input.resolve();
await super.setInput(input, options, CancellationToken.None); await super.setInput(input, options, context, CancellationToken.None);
this.view.showPlan(input.planXml!); this.view.showPlan(input.planXml!);
} }

View File

@@ -8,16 +8,16 @@ import { DisposableStore } from 'vs/base/common/lifecycle';
import { CancellationToken } from 'vs/base/common/cancellation'; import { CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStorageService } from 'vs/platform/storage/common/storage';
import * as DOM from 'vs/base/browser/dom'; import * as DOM from 'vs/base/browser/dom';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor'; import { EditorOptions, IEditorOpenContext } from 'vs/workbench/common/editor';
import { EditorOptions } from 'vs/workbench/common/editor';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService'; import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IResourceViewerStateChangedEvent } from 'sql/workbench/common/editor/resourceViewer/resourceViewerState'; import { IResourceViewerStateChangedEvent } from 'sql/workbench/common/editor/resourceViewer/resourceViewerState';
import { ResourceViewerInput } from 'sql/workbench/browser/editor/resourceViewer/resourceViewerInput'; import { ResourceViewerInput } from 'sql/workbench/browser/editor/resourceViewer/resourceViewerInput';
import { ResourceViewerTable } from 'sql/workbench/contrib/resourceViewer/browser/resourceViewerTable'; import { ResourceViewerTable } from 'sql/workbench/contrib/resourceViewer/browser/resourceViewerTable';
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
export class ResourceViewerEditor extends BaseEditor { export class ResourceViewerEditor extends EditorPane {
public static readonly ID: string = 'workbench.editor.resource-viewer'; public static readonly ID: string = 'workbench.editor.resource-viewer';
private _container!: HTMLElement; private _container!: HTMLElement;
@@ -72,8 +72,8 @@ export class ResourceViewerEditor extends BaseEditor {
return this._input as ResourceViewerInput; return this._input as ResourceViewerInput;
} }
public async setInput(input: ResourceViewerInput, options?: EditorOptions): Promise<void> { async setInput(input: ResourceViewerInput, options: EditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
await super.setInput(input, options, CancellationToken.None); await super.setInput(input, options, context, token);
this._inputDisposables.clear(); this._inputDisposables.clear();

View File

@@ -25,6 +25,7 @@
}, },
"lib": [ "lib": [
"ES2015", "ES2015",
"ES2016.Array.Include",
"ES2017.String", "ES2017.String",
"ES2018.Promise", "ES2018.Promise",
"DOM", "DOM",

View File

@@ -15,7 +15,6 @@
"include": [ "include": [
"typings/require.d.ts", "typings/require.d.ts",
"typings/thenable.d.ts", "typings/thenable.d.ts",
"typings/lib.array-ext.d.ts",
"vs/css.d.ts", "vs/css.d.ts",
"vs/monaco.d.ts", "vs/monaco.d.ts",
"vs/nls.d.ts", "vs/nls.d.ts",

View File

@@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as dom from 'vs/base/browser/dom';
import { renderCodiconsRegex } from 'vs/base/common/codicons';
export function renderCodiconsAsElement(text: string): Array<HTMLSpanElement | string> {
const elements = new Array<HTMLSpanElement | string>();
let match: RegExpMatchArray | null;
let textStart = 0, textStop = 0;
while ((match = renderCodiconsRegex.exec(text)) !== null) {
textStop = match.index || 0;
elements.push(text.substring(textStart, textStop));
textStart = (match.index || 0) + match[0].length;
const [, escaped, codicon, name, animation] = match;
elements.push(escaped ? `$(${codicon})` : dom.$(`span.codicon.codicon-${name}${animation ? `.codicon-animation-${animation}` : ''}`));
}
if (textStart < text.length) {
elements.push(text.substring(textStart));
}
return elements;
}

View File

@@ -997,6 +997,11 @@ export function trackFocus(element: HTMLElement | Window): IFocusTracker {
return new FocusTracker(element); return new FocusTracker(element);
} }
export function after<T extends Node>(sibling: HTMLElement, child: T): T {
sibling.after(child);
return child;
}
export function append<T extends Node>(parent: HTMLElement, ...children: T[]): T { export function append<T extends Node>(parent: HTMLElement, ...children: T[]): T {
children.forEach(child => parent.appendChild(child)); children.forEach(child => parent.appendChild(child));
return children[children.length - 1]; return children[children.length - 1];
@@ -1009,6 +1014,18 @@ export function prepend<T extends Node>(parent: HTMLElement, child: T): T {
const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((\.([\w\-]+))*)/; const SELECTOR_REGEX = /([\w\-]+)?(#([\w\-]+))?((\.([\w\-]+))*)/;
export function reset<T extends Node>(parent: HTMLElement, ...children: Array<Node | string>) {
parent.innerText = '';
coalesce(children)
.forEach(child => {
if (child instanceof Node) {
parent.appendChild(child);
} else {
parent.appendChild(document.createTextNode(child as string));
}
});
}
export enum Namespace { export enum Namespace {
HTML = 'http://www.w3.org/1999/xhtml', HTML = 'http://www.w3.org/1999/xhtml',
SVG = 'http://www.w3.org/2000/svg' SVG = 'http://www.w3.org/2000/svg'

View File

@@ -205,6 +205,40 @@ const altKeyMod = KeyMod.Alt;
const shiftKeyMod = KeyMod.Shift; const shiftKeyMod = KeyMod.Shift;
const metaKeyMod = (platform.isMacintosh ? KeyMod.CtrlCmd : KeyMod.WinCtrl); const metaKeyMod = (platform.isMacintosh ? KeyMod.CtrlCmd : KeyMod.WinCtrl);
export function printKeyboardEvent(e: KeyboardEvent): string {
let modifiers: string[] = [];
if (e.ctrlKey) {
modifiers.push(`ctrl`);
}
if (e.shiftKey) {
modifiers.push(`shift`);
}
if (e.altKey) {
modifiers.push(`alt`);
}
if (e.metaKey) {
modifiers.push(`meta`);
}
return `modifiers: [${modifiers.join(',')}], code: ${e.code}, keyCode: ${e.keyCode}, key: ${e.key}`;
}
export function printStandardKeyboardEvent(e: StandardKeyboardEvent): string {
let modifiers: string[] = [];
if (e.ctrlKey) {
modifiers.push(`ctrl`);
}
if (e.shiftKey) {
modifiers.push(`shift`);
}
if (e.altKey) {
modifiers.push(`alt`);
}
if (e.metaKey) {
modifiers.push(`meta`);
}
return `modifiers: [${modifiers.join(',')}], code: ${e.code}, keyCode: ${e.keyCode} ('${KeyCodeUtils.toString(e.keyCode)}')`;
}
export class StandardKeyboardEvent implements IKeyboardEvent { export class StandardKeyboardEvent implements IKeyboardEvent {
readonly _standardKeyboardEventBrand = true; readonly _standardKeyboardEventBrand = true;

View File

@@ -12,8 +12,7 @@ import { mixin } from 'vs/base/common/objects';
import { Event as BaseEvent, Emitter } from 'vs/base/common/event'; import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle'; import { Disposable } from 'vs/base/common/lifecycle';
import { Gesture, EventType } from 'vs/base/browser/touch'; import { Gesture, EventType } from 'vs/base/browser/touch';
import { renderCodicons } from 'vs/base/common/codicons'; import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
import { escape } from 'vs/base/common/strings';
export interface IButtonOptions extends IButtonStyles { export interface IButtonOptions extends IButtonStyles {
readonly title?: boolean | string; readonly title?: boolean | string;
@@ -181,7 +180,7 @@ export class Button extends Disposable {
DOM.addClass(this._element, 'monaco-text-button'); DOM.addClass(this._element, 'monaco-text-button');
} }
if (this.options.supportCodicons) { if (this.options.supportCodicons) {
this._element.innerHTML = renderCodicons(escape(value)); DOM.reset(this._element, ...renderCodiconsAsElement(value));
} else { } else {
this._element.textContent = value; this._element.textContent = value;
} }

View File

@@ -3,8 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { escape } from 'vs/base/common/strings'; import { reset } from 'vs/base/browser/dom';
import { renderCodicons } from 'vs/base/common/codicons'; import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
export class CodiconLabel { export class CodiconLabel {
@@ -13,7 +13,7 @@ export class CodiconLabel {
) { } ) { }
set text(text: string) { set text(text: string) {
this._container.innerHTML = renderCodicons(escape(text ?? '')); reset(this._container, ...renderCodiconsAsElement(text ?? ''));
} }
set title(title: string) { set title(title: string) {

View File

@@ -121,7 +121,7 @@ export class ExternalElementsDragAndDropData<T> implements IDragAndDropData {
} }
} }
export class DesktopDragAndDropData implements IDragAndDropData { export class NativeDragAndDropData implements IDragAndDropData {
readonly types: any[]; readonly types: any[];
readonly files: any[]; readonly files: any[];
@@ -976,7 +976,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
return false; return false;
} }
this.currentDragData = new DesktopDragAndDropData(); this.currentDragData = new NativeDragAndDropData();
} }
} }

View File

@@ -24,6 +24,7 @@ export interface IPaneOptions {
expanded?: boolean; expanded?: boolean;
orientation?: Orientation; orientation?: Orientation;
title: string; title: string;
titleDescription?: string;
} }
export interface IPaneStyles { export interface IPaneStyles {

View File

@@ -590,17 +590,6 @@ export function asArray<T>(x: T | T[]): T[] {
return Array.isArray(x) ? x : [x]; return Array.isArray(x) ? x : [x];
} }
/**
* @deprecated Use `Array.from` or `[...iter]`
*/
export function toArray<T>(iterable: IterableIterator<T>): T[] {
const result: T[] = [];
for (let element of iterable) {
result.push(element);
}
return result;
}
export function getRandomElement<T>(arr: T[]): T | undefined { export function getRandomElement<T>(arr: T[]): T | undefined {
return arr[Math.floor(Math.random() * arr.length)]; return arr[Math.floor(Math.random() * arr.length)];
} }

View File

@@ -170,6 +170,25 @@ export class Sequencer {
} }
} }
export class SequencerByKey<TKey> {
private promiseMap = new Map<TKey, Promise<any>>();
queue<T>(key: TKey, promiseTask: ITask<Promise<T>>): Promise<T> {
const runningPromise = this.promiseMap.get(key) ?? Promise.resolve();
const newPromise = runningPromise
.catch(() => { })
.then(promiseTask)
.finally(() => {
if (this.promiseMap.get(key) === newPromise) {
this.promiseMap.delete(key);
}
});
this.promiseMap.set(key, newPromise);
return newPromise;
}
}
/** /**
* A helper to delay execution of a task that is being requested often. * A helper to delay execution of a task that is being requested often.
* *

View File

@@ -499,7 +499,11 @@ export function markdownUnescapeCodicons(text: string): string {
return text.replace(markdownUnescapeCodiconsRegex, (match, escaped, codicon) => escaped ? match : `$(${codicon})`); return text.replace(markdownUnescapeCodiconsRegex, (match, escaped, codicon) => escaped ? match : `$(${codicon})`);
} }
const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi; export const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
/**
* @deprecated Use `renderCodiconsAsElement` instead
*/
export function renderCodicons(text: string): string { export function renderCodicons(text: string): string {
return text.replace(renderCodiconsRegex, (_, escaped, codicon, name, animation) => { return text.replace(renderCodiconsRegex, (_, escaped, codicon, name, animation) => {
// If the class for codicons is changed, it should also be updated in src\vs\base\browser\markdownRenderer.ts // If the class for codicons is changed, it should also be updated in src\vs\base\browser\markdownRenderer.ts

View File

@@ -142,7 +142,7 @@ export function isUNC(path: string): boolean {
// Reference: https://en.wikipedia.org/wiki/Filename // Reference: https://en.wikipedia.org/wiki/Filename
const WINDOWS_INVALID_FILE_CHARS = /[\\/:\*\?"<>\|]/g; const WINDOWS_INVALID_FILE_CHARS = /[\\/:\*\?"<>\|]/g;
const UNIX_INVALID_FILE_CHARS = /[\\/]/g; const UNIX_INVALID_FILE_CHARS = /[\\/]/g;
const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])$/i; const WINDOWS_FORBIDDEN_NAMES = /^(con|prn|aux|clock\$|nul|lpt[0-9]|com[0-9])(\.(.*?))?$/i;
export function isValidBasename(name: string | null | undefined, isWindowsOS: boolean = isWindows): boolean { export function isValidBasename(name: string | null | undefined, isWindowsOS: boolean = isWindows): boolean {
const invalidFileChars = isWindowsOS ? WINDOWS_INVALID_FILE_CHARS : UNIX_INVALID_FILE_CHARS; const invalidFileChars = isWindowsOS ? WINDOWS_INVALID_FILE_CHARS : UNIX_INVALID_FILE_CHARS;

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { compareAnything } from 'vs/base/common/comparers'; import { compareAnything } from 'vs/base/common/comparers';
import { matchesPrefix, IMatch, isUpper, fuzzyScore, createMatches as createFuzzyMatches, matchesStrictPrefix } from 'vs/base/common/filters'; import { matchesPrefix, IMatch, isUpper, fuzzyScore, createMatches as createFuzzyMatches } from 'vs/base/common/filters';
import { sep } from 'vs/base/common/path'; import { sep } from 'vs/base/common/path';
import { isWindows, isLinux } from 'vs/base/common/platform'; import { isWindows, isLinux } from 'vs/base/common/platform';
import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings'; import { stripWildcards, equalsIgnoreCase } from 'vs/base/common/strings';
@@ -369,9 +369,8 @@ export interface IItemAccessor<T> {
} }
const PATH_IDENTITY_SCORE = 1 << 18; const PATH_IDENTITY_SCORE = 1 << 18;
const LABEL_PREFIX_SCORE_MATCHCASE = 1 << 17; const LABEL_PREFIX_SCORE_THRESHOLD = 1 << 17;
const LABEL_PREFIX_SCORE_IGNORECASE = 1 << 16; const LABEL_SCORE_THRESHOLD = 1 << 16;
const LABEL_SCORE_THRESHOLD = 1 << 15;
export function scoreItemFuzzy<T>(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor<T>, cache: FuzzyScorerCache): IItemScore { export function scoreItemFuzzy<T>(item: T, query: IPreparedQuery, fuzzy: boolean, accessor: IItemAccessor<T>, cache: FuzzyScorerCache): IItemScore {
if (!item || !query.normalized) { if (!item || !query.normalized) {
@@ -460,20 +459,33 @@ function doScoreItemFuzzyMultiple(label: string, description: string | undefined
function doScoreItemFuzzySingle(label: string, description: string | undefined, path: string | undefined, query: IPreparedQueryPiece, preferLabelMatches: boolean, fuzzy: boolean): IItemScore { function doScoreItemFuzzySingle(label: string, description: string | undefined, path: string | undefined, query: IPreparedQueryPiece, preferLabelMatches: boolean, fuzzy: boolean): IItemScore {
// Prefer label matches if told so // Prefer label matches if told so or we have no description
if (preferLabelMatches) { if (preferLabelMatches || !description) {
// Treat prefix matches on the label highest
const prefixLabelMatchIgnoreCase = matchesPrefix(query.normalized, label);
if (prefixLabelMatchIgnoreCase) {
const prefixLabelMatchStrictCase = matchesStrictPrefix(query.normalized, label);
return { score: prefixLabelMatchStrictCase ? LABEL_PREFIX_SCORE_MATCHCASE : LABEL_PREFIX_SCORE_IGNORECASE, labelMatch: prefixLabelMatchStrictCase || prefixLabelMatchIgnoreCase };
}
// Second, score fuzzy
const [labelScore, labelPositions] = scoreFuzzy(label, query.normalized, query.normalizedLowercase, fuzzy); const [labelScore, labelPositions] = scoreFuzzy(label, query.normalized, query.normalizedLowercase, fuzzy);
if (labelScore) { if (labelScore) {
return { score: labelScore + LABEL_SCORE_THRESHOLD, labelMatch: createMatches(labelPositions) };
// If we have a prefix match on the label, we give a much
// higher baseScore to elevate these matches over others
// This ensures that typing a file name wins over results
// that are present somewhere in the label, but not the
// beginning.
const labelPrefixMatch = matchesPrefix(query.normalized, label);
let baseScore: number;
if (labelPrefixMatch) {
baseScore = LABEL_PREFIX_SCORE_THRESHOLD;
// We give another boost to labels that are short, e.g. given
// files "window.ts" and "windowActions.ts" and a query of
// "window", we want "window.ts" to receive a higher score.
// As such we compute the percentage the query has within the
// label and add that to the baseScore.
const prefixLengthBoost = Math.round((query.normalized.length / label.length) * 100);
baseScore += prefixLengthBoost;
} else {
baseScore = LABEL_SCORE_THRESHOLD;
}
return { score: baseScore + labelScore, labelMatch: labelPrefixMatch || createMatches(labelPositions) };
} }
} }
@@ -600,46 +612,19 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
} }
} }
// 2.) prefer label prefix matches (match case) // 2.) matches on label are considered higher compared to label+description matches
if (scoreA === LABEL_PREFIX_SCORE_MATCHCASE || scoreB === LABEL_PREFIX_SCORE_MATCHCASE) {
if (scoreA !== scoreB) {
return scoreA === LABEL_PREFIX_SCORE_MATCHCASE ? -1 : 1;
}
const labelA = accessor.getItemLabel(itemA) || '';
const labelB = accessor.getItemLabel(itemB) || '';
// prefer shorter names when both match on label prefix
if (labelA.length !== labelB.length) {
return labelA.length - labelB.length;
}
}
// 3.) prefer label prefix matches (ignore case)
if (scoreA === LABEL_PREFIX_SCORE_IGNORECASE || scoreB === LABEL_PREFIX_SCORE_IGNORECASE) {
if (scoreA !== scoreB) {
return scoreA === LABEL_PREFIX_SCORE_IGNORECASE ? -1 : 1;
}
const labelA = accessor.getItemLabel(itemA) || '';
const labelB = accessor.getItemLabel(itemB) || '';
// prefer shorter names when both match on label prefix
if (labelA.length !== labelB.length) {
return labelA.length - labelB.length;
}
}
// 4.) matches on label are considered higher compared to label+description matches
if (scoreA > LABEL_SCORE_THRESHOLD || scoreB > LABEL_SCORE_THRESHOLD) { if (scoreA > LABEL_SCORE_THRESHOLD || scoreB > LABEL_SCORE_THRESHOLD) {
if (scoreA !== scoreB) { if (scoreA !== scoreB) {
return scoreA > scoreB ? -1 : 1; return scoreA > scoreB ? -1 : 1;
} }
// prefer more compact matches over longer in label // prefer more compact matches over longer in label (unless this is a prefix match where
const comparedByMatchLength = compareByMatchLength(itemScoreA.labelMatch, itemScoreB.labelMatch); // longer prefix matches are actually preferred)
if (comparedByMatchLength !== 0) { if (scoreA < LABEL_PREFIX_SCORE_THRESHOLD && scoreB < LABEL_PREFIX_SCORE_THRESHOLD) {
return comparedByMatchLength; const comparedByMatchLength = compareByMatchLength(itemScoreA.labelMatch, itemScoreB.labelMatch);
if (comparedByMatchLength !== 0) {
return comparedByMatchLength;
}
} }
// prefer shorter labels over longer labels // prefer shorter labels over longer labels
@@ -650,12 +635,12 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
} }
} }
// 5.) compare by score in label+description // 3.) compare by score in label+description
if (scoreA !== scoreB) { if (scoreA !== scoreB) {
return scoreA > scoreB ? -1 : 1; return scoreA > scoreB ? -1 : 1;
} }
// 6.) scores are identical: prefer matches in label over non-label matches // 4.) scores are identical: prefer matches in label over non-label matches
const itemAHasLabelMatches = Array.isArray(itemScoreA.labelMatch) && itemScoreA.labelMatch.length > 0; const itemAHasLabelMatches = Array.isArray(itemScoreA.labelMatch) && itemScoreA.labelMatch.length > 0;
const itemBHasLabelMatches = Array.isArray(itemScoreB.labelMatch) && itemScoreB.labelMatch.length > 0; const itemBHasLabelMatches = Array.isArray(itemScoreB.labelMatch) && itemScoreB.labelMatch.length > 0;
if (itemAHasLabelMatches && !itemBHasLabelMatches) { if (itemAHasLabelMatches && !itemBHasLabelMatches) {
@@ -664,14 +649,14 @@ export function compareItemsByFuzzyScore<T>(itemA: T, itemB: T, query: IPrepared
return 1; return 1;
} }
// 7.) scores are identical: prefer more compact matches (label and description) // 5.) scores are identical: prefer more compact matches (label and description)
const itemAMatchDistance = computeLabelAndDescriptionMatchDistance(itemA, itemScoreA, accessor); const itemAMatchDistance = computeLabelAndDescriptionMatchDistance(itemA, itemScoreA, accessor);
const itemBMatchDistance = computeLabelAndDescriptionMatchDistance(itemB, itemScoreB, accessor); const itemBMatchDistance = computeLabelAndDescriptionMatchDistance(itemB, itemScoreB, accessor);
if (itemAMatchDistance && itemBMatchDistance && itemAMatchDistance !== itemBMatchDistance) { if (itemAMatchDistance && itemBMatchDistance && itemAMatchDistance !== itemBMatchDistance) {
return itemBMatchDistance > itemAMatchDistance ? -1 : 1; return itemBMatchDistance > itemAMatchDistance ? -1 : 1;
} }
// 8.) scores are identical: start to use the fallback compare // 6.) scores are identical: start to use the fallback compare
return fallbackCompare(itemA, itemB, query, accessor); return fallbackCompare(itemA, itemB, query, accessor);
} }

View File

@@ -45,7 +45,7 @@ export class MarkdownString implements IMarkdownString {
// escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash
this._value += (this._supportThemeIcons ? escapeCodicons(value) : value) this._value += (this._supportThemeIcons ? escapeCodicons(value) : value)
.replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&') .replace(/[\\`*_{}[\]()#+\-.!]/g, '\\$&')
.replace('\n', '\n\n'); .replace(/\n/g, '\n\n');
return this; return this;
} }

View File

@@ -5,7 +5,7 @@
import { VSBuffer } from 'vs/base/common/buffer'; import { VSBuffer } from 'vs/base/common/buffer';
import { regExpFlags } from 'vs/base/common/strings'; import { regExpFlags } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri'; import { URI, UriComponents } from 'vs/base/common/uri';
export function stringify(obj: any): string { export function stringify(obj: any): string {
return JSON.stringify(obj, replacer); return JSON.stringify(obj, replacer);
@@ -33,7 +33,15 @@ function replacer(key: string, value: any): any {
return value; return value;
} }
export function revive(obj: any, depth = 0): any {
type Deserialize<T> = T extends UriComponents ? URI
: T extends object
? Revived<T>
: T;
export type Revived<T> = { [K in keyof T]: Deserialize<T[K]> };
export function revive<T = any>(obj: any, depth = 0): Revived<T> {
if (!obj || depth > 200) { if (!obj || depth > 200) {
return obj; return obj;
} }
@@ -41,15 +49,15 @@ export function revive(obj: any, depth = 0): any {
if (typeof obj === 'object') { if (typeof obj === 'object') {
switch ((<MarshalledObject>obj).$mid) { switch ((<MarshalledObject>obj).$mid) {
case 1: return URI.revive(obj); case 1: return <any>URI.revive(obj);
case 2: return new RegExp(obj.source, obj.flags); case 2: return <any>new RegExp(obj.source, obj.flags);
} }
if ( if (
obj instanceof VSBuffer obj instanceof VSBuffer
|| obj instanceof Uint8Array || obj instanceof Uint8Array
) { ) {
return obj; return <any>obj;
} }
if (Array.isArray(obj)) { if (Array.isArray(obj)) {

View File

@@ -33,7 +33,7 @@ export interface ReadableStreamEvents<T> {
/** /**
* A interface that emulates the API shape of a node.js readable * A interface that emulates the API shape of a node.js readable
* stream for use in desktop and web environments. * stream for use in native and web environments.
*/ */
export interface ReadableStream<T> extends ReadableStreamEvents<T> { export interface ReadableStream<T> extends ReadableStreamEvents<T> {
@@ -60,7 +60,7 @@ export interface ReadableStream<T> extends ReadableStreamEvents<T> {
/** /**
* A interface that emulates the API shape of a node.js readable * A interface that emulates the API shape of a node.js readable
* for use in desktop and web environments. * for use in native and web environments.
*/ */
export interface Readable<T> { export interface Readable<T> {
@@ -73,7 +73,7 @@ export interface Readable<T> {
/** /**
* A interface that emulates the API shape of a node.js writeable * A interface that emulates the API shape of a node.js writeable
* stream for use in desktop and web environments. * stream for use in native and web environments.
*/ */
export interface WriteableStream<T> extends ReadableStream<T> { export interface WriteableStream<T> extends ReadableStream<T> {

View File

@@ -258,14 +258,12 @@ export type UriDto<T> = { [K in keyof T]: T[K] extends URI
/** /**
* Mapped-type that replaces all occurrences of URI with UriComponents and * Mapped-type that replaces all occurrences of URI with UriComponents and
* drops all functions. * drops all functions.
* todo@joh use toJSON-results
*/ */
export type Dto<T> = { [K in keyof T]: T[K] extends URI export type Dto<T> = T extends { toJSON(): infer U }
? UriComponents ? U
: T[K] extends Function : T extends object
? never ? { [k in keyof T]: Dto<T[k]>; }
: UriDto<T[K]> }; : T;
export function NotImplementedProxy<T>(name: string): { new(): T } { export function NotImplementedProxy<T>(name: string): { new(): T } {
return <any>class { return <any>class {

View File

@@ -93,6 +93,14 @@
process: { process: {
platform: process.platform, platform: process.platform,
env: process.env, env: process.env,
_whenEnvResolved: undefined,
get whenEnvResolved() {
if (!this._whenEnvResolved) {
this._whenEnvResolved = resolveEnv();
}
return this._whenEnvResolved;
},
on: on:
/** /**
* @param {string} type * @param {string} type
@@ -157,5 +165,33 @@
return true; return true;
} }
/**
* If VSCode is not run from a terminal, we should resolve additional
* shell specific environment from the OS shell to ensure we are seeing
* all development related environment variables. We do this from the
* main process because it may involve spawning a shell.
*/
function resolveEnv() {
return new Promise(function (resolve) {
const handle = setTimeout(function () {
console.warn('Preload: Unable to resolve shell environment in a reasonable time');
// It took too long to fetch the shell environment, return
resolve();
}, 3000);
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
clearTimeout(handle);
// Assign all keys of the shell environment to our process environment
Object.assign(process.env, shellEnv);
resolve();
});
ipcRenderer.send('vscode:fetchShellEnv');
});
}
//#endregion //#endregion
}()); }());

View File

@@ -84,6 +84,12 @@ export const process = (window as any).vscode.process as {
*/ */
env: { [key: string]: string | undefined }; env: { [key: string]: string | undefined };
/**
* Allows to await resolving the full process environment by checking for the shell environment
* of the OS in certain cases (e.g. when the app is started from the Dock on macOS).
*/
whenEnvResolved: Promise<void>;
/** /**
* A listener on the process. Only a small subset of listener types are allowed. * A listener on the process. Only a small subset of listener types are allowed.
*/ */

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { Database, Statement } from 'vscode-sqlite3'; import type { Database, Statement } from 'vscode-sqlite3';
import { Event } from 'vs/base/common/event'; import { Event } from 'vs/base/common/event';
import { timeout } from 'vs/base/common/async'; import { timeout } from 'vs/base/common/async';
import { mapToString, setToString } from 'vs/base/common/map'; import { mapToString, setToString } from 'vs/base/common/map';

View File

@@ -0,0 +1,52 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
import * as assert from 'assert';
suite('renderCodicons', () => {
test('no codicons', () => {
const result = renderCodiconsAsElement(' hello World .');
assert.equal(elementsToString(result), ' hello World .');
});
test('codicon only', () => {
const result = renderCodiconsAsElement('$(alert)');
assert.equal(elementsToString(result), '<span class="codicon codicon-alert"></span>');
});
test('codicon and non-codicon strings', () => {
const result = renderCodiconsAsElement(` $(alert) Unresponsive`);
assert.equal(elementsToString(result), ' <span class="codicon codicon-alert"></span> Unresponsive');
});
test('multiple codicons', () => {
const result = renderCodiconsAsElement('$(check)$(error)');
assert.equal(elementsToString(result), '<span class="codicon codicon-check"></span><span class="codicon codicon-error"></span>');
});
test('escaped codicon', () => {
const result = renderCodiconsAsElement('\\$(escaped)');
assert.equal(elementsToString(result), '$(escaped)');
});
test('codicon with animation', () => {
const result = renderCodiconsAsElement('$(zip~anim)');
assert.equal(elementsToString(result), '<span class="codicon codicon-zip codicon-animation-anim"></span>');
});
const elementsToString = (elements: Array<HTMLElement | string>): string => {
return elements
.map(elem => elem instanceof HTMLElement ? elem.outerHTML : elem)
.reduce((a, b) => a + b, '');
};
});

View File

@@ -688,4 +688,22 @@ suite('Async', () => {
assert.ok(Date.now() - now < 100); assert.ok(Date.now() - now < 100);
assert.equal(timedout, false); assert.equal(timedout, false);
}); });
test('SequencerByKey', async () => {
const s = new async.SequencerByKey<string>();
const r1 = await s.queue('key1', () => Promise.resolve('hello'));
assert.equal(r1, 'hello');
await s.queue('key2', () => Promise.reject(new Error('failed'))).then(() => {
throw new Error('should not be resolved');
}, err => {
// Expected error
assert.equal(err.message, 'failed');
});
// Still works after a queued promise is rejected
const r3 = await s.queue('key2', () => Promise.resolve('hello'));
assert.equal(r3, 'hello');
});
}); });

View File

@@ -57,6 +57,13 @@ suite('Paths', () => {
assert.ok(!extpath.isValidBasename('aux')); assert.ok(!extpath.isValidBasename('aux'));
assert.ok(!extpath.isValidBasename('Aux')); assert.ok(!extpath.isValidBasename('Aux'));
assert.ok(!extpath.isValidBasename('LPT0')); assert.ok(!extpath.isValidBasename('LPT0'));
assert.ok(!extpath.isValidBasename('aux.txt'));
assert.ok(!extpath.isValidBasename('com0.abc'));
assert.ok(extpath.isValidBasename('LPT00'));
assert.ok(extpath.isValidBasename('aux1'));
assert.ok(extpath.isValidBasename('aux1.txt'));
assert.ok(extpath.isValidBasename('aux1.aux.txt'));
assert.ok(!extpath.isValidBasename('test.txt.')); assert.ok(!extpath.isValidBasename('test.txt.'));
assert.ok(!extpath.isValidBasename('test.txt..')); assert.ok(!extpath.isValidBasename('test.txt..'));
assert.ok(!extpath.isValidBasename('test.txt ')); assert.ok(!extpath.isValidBasename('test.txt '));

View File

@@ -1025,6 +1025,51 @@ suite('Fuzzy Scorer', () => {
assert.equal(res[1], resourceB); assert.equal(res[1], resourceB);
}); });
test('compareFilesByScore - boost better prefix match if multiple queries are used', function () {
const resourceA = URI.file('src/vs/workbench/services/host/browser/browserHostService.ts');
const resourceB = URI.file('src/vs/workbench/browser/workbench.ts');
for (const query of ['workbench.ts browser', 'browser workbench.ts', 'browser workbench', 'workbench browser']) {
let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
res = [resourceB, resourceA].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
}
});
test('compareFilesByScore - boost shorter prefix match if multiple queries are used', function () {
const resourceA = URI.file('src/vs/workbench/browser/actions/windowActions.ts');
const resourceB = URI.file('src/vs/workbench/electron-browser/window.ts');
for (const query of ['window browser', 'window.ts browser']) {
let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
res = [resourceB, resourceA].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
}
});
test('compareFilesByScore - boost shorter prefix match if multiple queries are used (#99171)', function () {
const resourceA = URI.file('mesh_editor_lifetime_job.h');
const resourceB = URI.file('lifetime_job.h');
for (const query of ['m life, life m']) {
let res = [resourceA, resourceB].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
res = [resourceB, resourceA].sort((r1, r2) => compareItemsByScore(r1, r2, query, true, ResourceAccessor));
assert.equal(res[0], resourceB);
assert.equal(res[1], resourceA);
}
});
test('prepareQuery', () => { test('prepareQuery', () => {
assert.equal(scorer.prepareQuery(' f*a ').normalized, 'fa'); assert.equal(scorer.prepareQuery(' f*a ').normalized, 'fa');
assert.equal(scorer.prepareQuery('model Tester.ts').original, 'model Tester.ts'); assert.equal(scorer.prepareQuery('model Tester.ts').original, 'model Tester.ts');

View File

@@ -17,6 +17,9 @@
<!-- Builtin Extensions (running out of sources) --> <!-- Builtin Extensions (running out of sources) -->
<meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}"> <meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}">
<!-- Workbench Credentials (running out of sources) -->
<meta id="vscode-workbench-credentials" data-settings="{{WORKBENCH_CREDENTIALS}}">
<!-- Workarounds/Hacks (remote user data uri) --> <!-- Workarounds/Hacks (remote user data uri) -->
<meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}"> <meta id="vscode-remote-user-data-uri" data-settings="{{REMOTE_USER_DATA_URI}}">

View File

@@ -3,8 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, ICommand, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api'; import { IWorkbenchConstructionOptions, create, ICredentialsProvider, IURLCallbackProvider, IWorkspaceProvider, IWorkspace, IWindowIndicator, IHomeIndicator, IProductQualityChangeHandler } from 'vs/workbench/workbench.web.api';
import product from 'vs/platform/product/common/product';
import { URI, UriComponents } from 'vs/base/common/uri'; import { URI, UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event'; import { Event, Emitter } from 'vs/base/common/event';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
@@ -16,6 +15,7 @@ import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/wi
import { isEqual } from 'vs/base/common/resources'; import { isEqual } from 'vs/base/common/resources';
import { isStandalone } from 'vs/base/browser/browser'; import { isStandalone } from 'vs/base/browser/browser';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
import { Schemas } from 'vs/base/common/network';
interface ICredential { interface ICredential {
service: string; service: string;
@@ -27,6 +27,13 @@ class LocalStorageCredentialsProvider implements ICredentialsProvider {
static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider'; static readonly CREDENTIALS_OPENED_KEY = 'credentials.provider';
constructor(credentials: ICredential[]) {
this._credentials = credentials;
for (const { service, account, password } of this._credentials) {
this.setPassword(service, account, password);
}
}
private _credentials: ICredential[] | undefined; private _credentials: ICredential[] | undefined;
private get credentials(): ICredential[] { private get credentials(): ICredential[] {
if (!this._credentials) { if (!this._credentials) {
@@ -277,6 +284,20 @@ class WorkspaceProvider implements IWorkspaceProvider {
return false; return false;
} }
hasRemote(): boolean {
if (this.workspace) {
if (isFolderToOpen(this.workspace)) {
return this.workspace.folderUri.scheme === Schemas.vscodeRemote;
}
if (isWorkspaceToOpen(this.workspace)) {
return this.workspace.workspaceUri.scheme === Schemas.vscodeRemote;
}
}
return true;
}
} }
class WindowIndicator implements IWindowIndicator { class WindowIndicator implements IWindowIndicator {
@@ -287,8 +308,6 @@ class WindowIndicator implements IWindowIndicator {
readonly tooltip: string; readonly tooltip: string;
readonly command: string | undefined; readonly command: string | undefined;
readonly commandImpl: ICommand | undefined = undefined;
constructor(workspace: IWorkspace) { constructor(workspace: IWorkspace) {
let repositoryOwner: string | undefined = undefined; let repositoryOwner: string | undefined = undefined;
let repositoryName: string | undefined = undefined; let repositoryName: string | undefined = undefined;
@@ -306,20 +325,16 @@ class WindowIndicator implements IWindowIndicator {
} }
} }
// Repo
if (repositoryName && repositoryOwner) { if (repositoryName && repositoryOwner) {
this.label = localize('openInDesktopLabel', "$(remote) Open in Desktop"); this.label = localize('playgroundLabelRepository', "$(remote) VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
this.tooltip = localize('openInDesktopTooltip', "Open in Desktop"); this.tooltip = localize('playgroundRepositoryTooltip', "VS Code Web Playground: {0}/{1}", repositoryOwner, repositoryName);
this.command = '_web.openInDesktop'; }
this.commandImpl = {
id: this.command, // No Repo
handler: () => { else {
const protocol = product.quality === 'stable' ? 'vscode' : 'vscode-insiders'; this.label = localize('playgroundLabel', "$(remote) VS Code Web Playground");
window.open(`${protocol}://vscode.git/clone?url=${encodeURIComponent(`https://github.com/${repositoryOwner}/${repositoryName}.git`)}`); this.tooltip = localize('playgroundTooltip', "VS Code Web Playground");
}
};
} else {
this.label = localize('playgroundLabel', "Web Playground");
this.tooltip = this.label;
} }
} }
} }
@@ -391,6 +406,9 @@ class WindowIndicator implements IWindowIndicator {
} }
} }
// Workspace Provider
const workspaceProvider = new WorkspaceProvider(workspace, payload);
// Home Indicator // Home Indicator
const homeIndicator: IHomeIndicator = { const homeIndicator: IHomeIndicator = {
href: 'https://github.com/Microsoft/vscode', href: 'https://github.com/Microsoft/vscode',
@@ -398,13 +416,10 @@ class WindowIndicator implements IWindowIndicator {
title: localize('home', "Home") title: localize('home', "Home")
}; };
// Commands // Window indicator (unless connected to a remote)
const commands: ICommand[] = []; let windowIndicator: WindowIndicator | undefined = undefined;
if (!workspaceProvider.hasRemote()) {
// Window indicator windowIndicator = new WindowIndicator(workspace);
const windowIndicator = new WindowIndicator(workspace);
if (windowIndicator.commandImpl) {
commands.push(windowIndicator.commandImpl);
} }
// Product Quality Change Handler // Product Quality Change Handler
@@ -422,15 +437,19 @@ class WindowIndicator implements IWindowIndicator {
window.location.href = `${window.location.origin}?${queryString}`; window.location.href = `${window.location.origin}?${queryString}`;
}; };
// Find credentials from DOM
const credentialsElement = document.getElementById('vscode-workbench-credentials');
const credentialsElementAttribute = credentialsElement ? credentialsElement.getAttribute('data-settings') : undefined;
const credentialsProvider = new LocalStorageCredentialsProvider(credentialsElementAttribute ? JSON.parse(credentialsElementAttribute) : []);
// Finally create workbench // Finally create workbench
create(document.body, { create(document.body, {
...config, ...config,
homeIndicator, homeIndicator,
commands,
windowIndicator, windowIndicator,
productQualityChangeHandler, productQualityChangeHandler,
workspaceProvider: new WorkspaceProvider(workspace, payload), workspaceProvider,
urlCallbackProvider: new PollingURLCallbackProvider(), urlCallbackProvider: new PollingURLCallbackProvider(),
credentialsProvider: new LocalStorageCredentialsProvider() credentialsProvider
}); });
})(); })();

View File

@@ -33,8 +33,8 @@ const bootstrapWindow = (() => {
return window.MonacoBootstrapWindow; return window.MonacoBootstrapWindow;
})(); })();
// Setup shell environment // Load environment in parallel to workbench loading to avoid waterfall
process['lazyEnv'] = getLazyEnv(); const whenEnvResolved = bootstrapWindow.globals().process.whenEnvResolved;
// Load workbench main JS, CSS and NLS all in parallel. This is an // Load workbench main JS, CSS and NLS all in parallel. This is an
// optimization to prevent a waterfall of loading to happen, because // optimization to prevent a waterfall of loading to happen, because
@@ -46,18 +46,19 @@ bootstrapWindow.load([
'vs/nls!vs/workbench/workbench.desktop.main', 'vs/nls!vs/workbench/workbench.desktop.main',
'vs/css!vs/workbench/workbench.desktop.main' 'vs/css!vs/workbench/workbench.desktop.main'
], ],
function (workbench, configuration) { async function (workbench, configuration) {
// Mark start of workbench // Mark start of workbench
perf.mark('didLoadWorkbenchMain'); perf.mark('didLoadWorkbenchMain');
performance.mark('workbench-start'); performance.mark('workbench-start');
return process['lazyEnv'].then(function () { // Wait for process environment being fully resolved
perf.mark('main/startup'); await whenEnvResolved;
// @ts-ignore perf.mark('main/startup');
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
}); // @ts-ignore
return require('vs/workbench/electron-browser/desktop.main').main(configuration);
}, },
{ {
removeDeveloperKeybindingsAfterLoad: true, removeDeveloperKeybindingsAfterLoad: true,
@@ -77,7 +78,7 @@ bootstrapWindow.load([
* @param {{ * @param {{
* partsSplashPath?: string, * partsSplashPath?: string,
* highContrast?: boolean, * highContrast?: boolean,
* defaultThemeType?: string, * autoDetectHighContrast?: boolean,
* extensionDevelopmentPath?: string[], * extensionDevelopmentPath?: string[],
* folderUri?: object, * folderUri?: object,
* workspace?: object * workspace?: object
@@ -96,7 +97,8 @@ function showPartsSplash(configuration) {
} }
// high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts // high contrast mode has been turned on from the outside, e.g. OS -> ignore stored colors and layouts
if (data && configuration.highContrast && data.baseTheme !== 'hc-black') { const isHighContrast = configuration.highContrast && configuration.autoDetectHighContrast;
if (data && isHighContrast && data.baseTheme !== 'hc-black') {
data = undefined; data = undefined;
} }
@@ -111,14 +113,10 @@ function showPartsSplash(configuration) {
baseTheme = data.baseTheme; baseTheme = data.baseTheme;
shellBackground = data.colorInfo.editorBackground; shellBackground = data.colorInfo.editorBackground;
shellForeground = data.colorInfo.foreground; shellForeground = data.colorInfo.foreground;
} else if (configuration.highContrast || configuration.defaultThemeType === 'hc') { } else if (isHighContrast) {
baseTheme = 'hc-black'; baseTheme = 'hc-black';
shellBackground = '#000000'; shellBackground = '#000000';
shellForeground = '#FFFFFF'; shellForeground = '#FFFFFF';
} else if (configuration.defaultThemeType === 'vs') {
baseTheme = 'vs';
shellBackground = '#FFFFFF';
shellForeground = '#000000';
} else { } else {
baseTheme = 'vs-dark'; baseTheme = 'vs-dark';
shellBackground = '#1E1E1E'; shellBackground = '#1E1E1E';
@@ -172,26 +170,3 @@ function showPartsSplash(configuration) {
perf.mark('didShowPartsSplash'); perf.mark('didShowPartsSplash');
} }
/**
* @returns {Promise<void>}
*/
function getLazyEnv() {
const ipcRenderer = bootstrapWindow.globals().ipcRenderer;
return new Promise(function (resolve) {
const handle = setTimeout(function () {
resolve();
console.warn('renderer did not receive lazyEnv in time');
}, 10000);
ipcRenderer.once('vscode:acceptShellEnv', function (event, shellEnv) {
clearTimeout(handle);
Object.assign(process.env, shellEnv);
// @ts-ignore
resolve(process.env);
});
ipcRenderer.send('vscode:fetchShellEnv');
});
}

View File

@@ -50,7 +50,7 @@ import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/err
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener'; import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver'; import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService'; import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
import { RunOnceScheduler } from 'vs/base/common/async'; import { RunOnceScheduler, timeout } from 'vs/base/common/async';
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu'; import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
import { homedir } from 'os'; import { homedir } from 'os';
import { join, sep, posix } from 'vs/base/common/path'; import { join, sep, posix } from 'vs/base/common/path';
@@ -68,11 +68,11 @@ import { statSync } from 'fs';
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc'; import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService'; import { IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc'; import { ExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/common/extensionHostDebugIpc';
import { ElectronExtensionHostDebugBroadcastChannel } from 'vs/platform/debug/electron-main/extensionHostDebugIpc';
import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService'; import { IElectronMainService, ElectronMainService } from 'vs/platform/electron/electron-main/electronMainService';
import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService'; import { ISharedProcessMainService, SharedProcessMainService } from 'vs/platform/ipc/electron-main/sharedProcessMainService';
import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs'; import { IDialogMainService, DialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
import { withNullAsUndefined } from 'vs/base/common/types'; import { withNullAsUndefined } from 'vs/base/common/types';
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
import { coalesce } from 'vs/base/common/arrays'; import { coalesce } from 'vs/base/common/arrays';
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys'; import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc'; import { StorageKeysSyncRegistryChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
@@ -80,8 +80,6 @@ import { INativeEnvironmentService } from 'vs/platform/environment/node/environm
import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels'; import { mnemonicButtonLabel, getPathLabel } from 'vs/base/common/labels';
import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService'; import { WebviewMainService } from 'vs/platform/webview/electron-main/webviewMainService';
import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService'; import { IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
import { createServer, AddressInfo } from 'net';
import { IOpenExtensionWindowResult } from 'vs/platform/debug/common/extensionHostDebug';
import { IFileService } from 'vs/platform/files/common/files'; import { IFileService } from 'vs/platform/files/common/files';
import { stripComments } from 'vs/base/common/json'; import { stripComments } from 'vs/base/common/json';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
@@ -272,6 +270,12 @@ export class CodeApplication extends Disposable {
try { try {
const shellEnv = await getShellEnvironment(this.logService, this.environmentService); const shellEnv = await getShellEnvironment(this.logService, this.environmentService);
// TODO@sandbox workaround for https://github.com/electron/electron/issues/25119
if (this.environmentService.sandbox) {
await timeout(100);
}
if (!webContents.isDestroyed()) { if (!webContents.isDestroyed()) {
webContents.send('vscode:acceptShellEnv', shellEnv); webContents.send('vscode:acceptShellEnv', shellEnv);
} }
@@ -297,7 +301,7 @@ export class CodeApplication extends Disposable {
const nativeKeymap = await import('native-keymap'); const nativeKeymap = await import('native-keymap');
nativeKeymap.onDidChangeKeyboardLayout(() => { nativeKeymap.onDidChangeKeyboardLayout(() => {
if (this.windowsMainService) { if (this.windowsMainService) {
this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged', false); this.windowsMainService.sendToAll('vscode:keyboardLayoutChanged');
} }
}); });
})(); })();
@@ -364,17 +368,17 @@ export class CodeApplication extends Disposable {
const sharedProcess = this.instantiationService.createInstance(SharedProcess, machineId, this.userEnv); const sharedProcess = this.instantiationService.createInstance(SharedProcess, machineId, this.userEnv);
const sharedProcessClient = sharedProcess.whenIpcReady().then(() => { const sharedProcessClient = sharedProcess.whenIpcReady().then(() => {
this.logService.trace('Shared process: IPC ready'); this.logService.trace('Shared process: IPC ready');
return connect(this.environmentService.sharedIPCHandle, 'main'); return connect(this.environmentService.sharedIPCHandle, 'main');
}); });
const sharedProcessReady = sharedProcess.whenReady().then(() => { const sharedProcessReady = sharedProcess.whenReady().then(() => {
this.logService.trace('Shared process: init ready'); this.logService.trace('Shared process: init ready');
return sharedProcessClient; return sharedProcessClient;
}); });
this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => { this.lifecycleMainService.when(LifecycleMainPhase.AfterWindowOpen).then(() => {
this._register(new RunOnceScheduler(async () => { this._register(new RunOnceScheduler(async () => {
const userEnv = await getShellEnvironment(this.logService, this.environmentService); sharedProcess.spawn(await getShellEnvironment(this.logService, this.environmentService));
sharedProcess.spawn(userEnv);
}, 3000)).schedule(); }, 3000)).schedule();
}); });
@@ -847,6 +851,9 @@ export class CodeApplication extends Disposable {
} catch (error) { } catch (error) {
this.logService.error(error); this.logService.error(error);
} }
// Start to fetch shell environment after window has opened
getShellEnvironment(this.logService, this.environmentService);
} }
private handleRemoteAuthorities(): void { private handleRemoteAuthorities(): void {
@@ -858,100 +865,3 @@ export class CodeApplication extends Disposable {
}); });
} }
} }
class ElectronExtensionHostDebugBroadcastChannel<TContext> extends ExtensionHostDebugBroadcastChannel<TContext> {
constructor(private windowsMainService: IWindowsMainService) {
super();
}
call(ctx: TContext, command: string, arg?: any): Promise<any> {
if (command === 'openExtensionDevelopmentHostWindow') {
return this.openExtensionDevelopmentHostWindow(arg[0], arg[1], arg[2]);
} else {
return super.call(ctx, command, arg);
}
}
private async openExtensionDevelopmentHostWindow(args: string[], env: IProcessEnvironment, debugRenderer: boolean): Promise<IOpenExtensionWindowResult> {
const pargs = parseArgs(args, OPTIONS);
const extDevPaths = pargs.extensionDevelopmentPath;
if (!extDevPaths) {
return {};
}
const [codeWindow] = this.windowsMainService.openExtensionDevelopmentHostWindow(extDevPaths, {
context: OpenContext.API,
cli: pargs,
userEnv: Object.keys(env).length > 0 ? env : undefined
});
if (!debugRenderer) {
return {};
}
const debug = codeWindow.win.webContents.debugger;
let listeners = debug.isAttached() ? Infinity : 0;
const server = createServer(listener => {
if (listeners++ === 0) {
debug.attach();
}
let closed = false;
const writeMessage = (message: object) => {
if (!closed) { // in case sendCommand promises settle after closed
listener.write(JSON.stringify(message) + '\0'); // null-delimited, CDP-compatible
}
};
const onMessage = (_event: Event, method: string, params: unknown, sessionId?: string) =>
writeMessage(({ method, params, sessionId }));
codeWindow.win.on('close', () => {
debug.removeListener('message', onMessage);
listener.end();
closed = true;
});
debug.addListener('message', onMessage);
let buf = Buffer.alloc(0);
listener.on('data', data => {
buf = Buffer.concat([buf, data]);
for (let delimiter = buf.indexOf(0); delimiter !== -1; delimiter = buf.indexOf(0)) {
let data: { id: number; sessionId: string; params: {} };
try {
const contents = buf.slice(0, delimiter).toString('utf8');
buf = buf.slice(delimiter + 1);
data = JSON.parse(contents);
} catch (e) {
console.error('error reading cdp line', e);
}
// depends on a new API for which electron.d.ts has not been updated:
// @ts-ignore
debug.sendCommand(data.method, data.params, data.sessionId)
.then((result: object) => writeMessage({ id: data.id, sessionId: data.sessionId, result }))
.catch((error: Error) => writeMessage({ id: data.id, sessionId: data.sessionId, error: { code: 0, message: error.message } }));
}
});
listener.on('error', err => {
console.error('error on cdp pipe:', err);
});
listener.on('close', () => {
closed = true;
if (--listeners === 0) {
debug.detach();
}
});
});
await new Promise(r => server.listen(0, r));
codeWindow.win.on('close', () => server.close());
return { rendererDebugPort: (server.address() as AddressInfo).port };
}
}

View File

@@ -8,7 +8,7 @@ import * as objects from 'vs/base/common/objects';
import * as nls from 'vs/nls'; import * as nls from 'vs/nls';
import { Emitter } from 'vs/base/common/event'; import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri'; import { URI } from 'vs/base/common/uri';
import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event } from 'electron'; import { screen, BrowserWindow, systemPreferences, app, TouchBar, nativeImage, Rectangle, Display, TouchBarSegmentedControl, NativeImage, BrowserWindowConstructorOptions, SegmentedControlSegment, nativeTheme, Event, Details } from 'electron';
import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService'; import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
@@ -167,12 +167,23 @@ export class CodeWindow extends Disposable implements ICodeWindow {
title: product.nameLong, title: product.nameLong,
webPreferences: { webPreferences: {
preload: URI.parse(this.doGetPreloadUrl()).fsPath, preload: URI.parse(this.doGetPreloadUrl()).fsPath,
nodeIntegration: true,
enableWebSQL: false, enableWebSQL: false,
enableRemoteModule: false, enableRemoteModule: false,
nativeWindowOpen: true, nativeWindowOpen: true,
webviewTag: true, webviewTag: true,
zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel) zoomFactor: zoomLevelToZoomFactor(windowConfig?.zoomLevel),
...this.environmentService.sandbox ?
// Sandbox
{
sandbox: true,
contextIsolation: true
} :
// No Sandbox
{
nodeIntegration: true
}
} }
}; };
@@ -325,7 +336,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
return !!this.documentEdited; return !!this.documentEdited;
} }
focus(): void { focus(options?: { force: boolean }): void {
// macOS: Electron >6.x changed its behaviour to not
// bring the application to the foreground when a window
// is focused programmatically. Only via `app.focus` and
// the option `steal: true` can you get the previous
// behaviour back. The only reason to use this option is
// when a window is getting focused while the application
// is not in the foreground.
if (isMacintosh && options?.force) {
app.focus({ steal: true });
}
if (!this._win) { if (!this._win) {
return; return;
} }
@@ -392,7 +414,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
private registerListeners(): void { private registerListeners(): void {
// Crashes & Unrsponsive // Crashes & Unrsponsive
this._win.webContents.on('crashed', () => this.onWindowError(WindowError.CRASHED)); this._win.webContents.on('render-process-gone', (event, details) => this.onWindowError(WindowError.CRASHED, details));
this._win.on('unresponsive', () => this.onWindowError(WindowError.UNRESPONSIVE)); this._win.on('unresponsive', () => this.onWindowError(WindowError.UNRESPONSIVE));
// Window close // Window close
@@ -524,8 +546,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) }))); this.marketplaceHeadersPromise.then(headers => cb({ cancel: false, requestHeaders: Object.assign(details.requestHeaders, headers) })));
} }
private onWindowError(error: WindowError): void { private onWindowError(error: WindowError.UNRESPONSIVE): void;
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: renderer process crashed!' : '[VS Code]: detected unresponsive'); private onWindowError(error: WindowError.CRASHED, details: Details): void;
private onWindowError(error: WindowError, details?: Details): void {
this.logService.error(error === WindowError.CRASHED ? `[VS Code]: renderer process crashed (detail: ${details?.reason})` : '[VS Code]: detected unresponsive');
// If we run extension tests from CLI, showing a dialog is not // If we run extension tests from CLI, showing a dialog is not
// very helpful in this case. Rather, we bring down the test run // very helpful in this case. Rather, we bring down the test run
@@ -579,11 +603,18 @@ export class CodeWindow extends Disposable implements ICodeWindow {
// Crashed // Crashed
else { else {
let message: string;
if (details && details.reason !== 'crashed') {
message = nls.localize('appCrashedDetails', "The window has crashed (reason: '{0}')", details?.reason);
} else {
message = nls.localize('appCrashed', "The window has crashed", details?.reason);
}
this.dialogMainService.showMessageBox({ this.dialogMainService.showMessageBox({
title: product.nameLong, title: product.nameLong,
type: 'warning', type: 'warning',
buttons: [mnemonicButtonLabel(nls.localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(nls.localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))], buttons: [mnemonicButtonLabel(nls.localize({ key: 'reopen', comment: ['&& denotes a mnemonic'] }, "&&Reopen")), mnemonicButtonLabel(nls.localize({ key: 'close', comment: ['&& denotes a mnemonic'] }, "&&Close"))],
message: nls.localize('appCrashed', "The window has crashed"), message,
detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."), detail: nls.localize('appCrashedDetail', "We are sorry for the inconvenience! You can reopen the window to continue where you left off."),
noLink: true noLink: true
}, this._win).then(result => { }, this._win).then(result => {
@@ -699,7 +730,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
this.showTimeoutHandle = setTimeout(() => { this.showTimeoutHandle = setTimeout(() => {
if (this._win && !this._win.isVisible() && !this._win.isMinimized()) { if (this._win && !this._win.isVisible() && !this._win.isMinimized()) {
this._win.show(); this._win.show();
this._win.focus(); this.focus({ force: true });
this._win.webContents.openDevTools(); this._win.webContents.openDevTools();
} }
}, 10000); }, 10000);
@@ -754,11 +785,8 @@ export class CodeWindow extends Disposable implements ICodeWindow {
windowConfiguration.fullscreen = this.isFullScreen; windowConfiguration.fullscreen = this.isFullScreen;
// Set Accessibility Config // Set Accessibility Config
let autoDetectHighContrast = true; windowConfiguration.highContrast = nativeTheme.shouldUseInvertedColorScheme || nativeTheme.shouldUseHighContrastColors;
if (windowConfig?.autoDetectHighContrast === false) { windowConfiguration.autoDetectHighContrast = windowConfig?.autoDetectHighContrast ?? true;
autoDetectHighContrast = false;
}
windowConfiguration.highContrast = isWindows && autoDetectHighContrast && nativeTheme.shouldUseInvertedColorScheme;
windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled; windowConfiguration.accessibilitySupport = app.accessibilitySupportEnabled;
// Title style related // Title style related
@@ -799,7 +827,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
} }
private doGetUrl(config: object): string { private doGetUrl(config: object): string {
return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`; let workbench: string;
if (this.environmentService.sandbox) {
workbench = 'vs/code/electron-sandbox/workbench/workbench.html';
} else {
workbench = 'vs/code/electron-browser/workbench/workbench.html';
}
return `${require.toUrl(workbench)}?config=${encodeURIComponent(JSON.stringify(config))}`;
} }
private doGetPreloadUrl(): string { private doGetPreloadUrl(): string {

View File

@@ -8,7 +8,7 @@ import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron'; import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer, process } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { ipcRenderer, process } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window'; import { applyZoom, zoomIn, zoomOut } from 'vs/platform/windows/electron-sandbox/window';
import { $, windowOpenNoOpener, addClass } from 'vs/base/browser/dom'; import { $, reset, windowOpenNoOpener, addClass } from 'vs/base/browser/dom';
import { Button } from 'vs/base/browser/ui/button/button'; import { Button } from 'vs/base/browser/ui/button/button';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel'; import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
import * as collections from 'vs/base/common/collections'; import * as collections from 'vs/base/common/collections';
@@ -277,33 +277,25 @@ export class IssueReporter extends Disposable {
} }
private updateSettingsSearchDetails(data: ISettingsSearchIssueReporterData): void { private updateSettingsSearchDetails(data: ISettingsSearchIssueReporterData): void {
const target = document.querySelector('.block-settingsSearchResults .block-info'); const target = document.querySelector<HTMLElement>('.block-settingsSearchResults .block-info');
if (target) { if (target) {
const details = ` const queryDiv = $<HTMLDivElement>('div', undefined, `Query: "${data.query}"` as string);
<div class='block-settingsSearchResults-details'> const countDiv = $<HTMLElement>('div', undefined, `Literal match count: ${data.filterResultCount}` as string);
<div>Query: "${data.query}"</div> const detailsDiv = $<HTMLDivElement>('.block-settingsSearchResults-details', undefined, queryDiv, countDiv);
<div>Literal match count: ${data.filterResultCount}</div>
</div>
`;
let table = ` const table = $('table', undefined,
<tr> $('tr', undefined,
<th>Setting</th> $('th', undefined, 'Setting'),
<th>Extension</th> $('th', undefined, 'Extension'),
<th>Score</th> $('th', undefined, 'Score'),
</tr>`; ),
...data.actualSearchResults.map(setting => $('tr', undefined,
data.actualSearchResults $('td', undefined, setting.key),
.forEach(setting => { $('td', undefined, setting.extensionId),
table += ` $('td', undefined, String(setting.score).slice(0, 5)),
<tr> ))
<td>${setting.key}</td> );
<td>${setting.extensionId}</td> reset(target, detailsDiv, table);
<td>${String(setting.score).slice(0, 5)}</td>
</tr>`;
});
target.innerHTML = `${details}<table>${table}</table>`;
} }
} }
@@ -654,9 +646,9 @@ export class IssueReporter extends Disposable {
issueState.appendChild(issueIcon); issueState.appendChild(issueIcon);
issueState.appendChild(issueStateLabel); issueState.appendChild(issueStateLabel);
item = $('div.issue', {}, issueState, link); item = $('div.issue', undefined, issueState, link);
} else { } else {
item = $('div.issue', {}, link); item = $('div.issue', undefined, link);
} }
issues.appendChild(item); issues.appendChild(item);
@@ -672,19 +664,19 @@ export class IssueReporter extends Disposable {
} }
private setUpTypes(): void { private setUpTypes(): void {
const makeOption = (issueType: IssueType, description: string) => `<option value="${issueType.valueOf()}">${escape(description)}</option>`; const makeOption = (issueType: IssueType, description: string) => $('option', { 'value': issueType.valueOf() }, escape(description));
const typeSelect = this.getElementById('issue-type')! as HTMLSelectElement; const typeSelect = this.getElementById('issue-type')! as HTMLSelectElement;
const { issueType } = this.issueReporterModel.getData(); const { issueType } = this.issueReporterModel.getData();
if (issueType === IssueType.SettingsSearchIssue) { if (issueType === IssueType.SettingsSearchIssue) {
typeSelect.innerHTML = makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue")); reset(typeSelect, makeOption(IssueType.SettingsSearchIssue, localize('settingsSearchIssue', "Settings Search Issue")));
typeSelect.disabled = true; typeSelect.disabled = true;
} else { } else {
typeSelect.innerHTML = [ reset(typeSelect,
makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")), makeOption(IssueType.Bug, localize('bugReporter', "Bug Report")),
makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request")), makeOption(IssueType.FeatureRequest, localize('featureRequest', "Feature Request")),
makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue")) makeOption(IssueType.PerformanceIssue, localize('performanceIssue', "Performance Issue"))
].join('\n'); );
} }
typeSelect.value = issueType.toString(); typeSelect.value = issueType.toString();
@@ -774,9 +766,8 @@ export class IssueReporter extends Disposable {
} else { } else {
show(extensionsBlock); show(extensionsBlock);
} }
reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`; reset(descriptionSubtitle, localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
descriptionSubtitle.innerHTML = localize('bugDescription', "Share the steps needed to reliably reproduce the problem. Please include actual and expected results. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub.");
} else if (issueType === IssueType.PerformanceIssue) { } else if (issueType === IssueType.PerformanceIssue) {
show(blockContainer); show(blockContainer);
show(systemBlock); show(systemBlock);
@@ -790,11 +781,11 @@ export class IssueReporter extends Disposable {
show(extensionsBlock); show(extensionsBlock);
} }
descriptionTitle.innerHTML = `${localize('stepsToReproduce', "Steps to Reproduce")} <span class="required-input">*</span>`; reset(descriptionTitle, localize('stepsToReproduce', "Steps to Reproduce"), $('span.required-input', undefined, '*'));
descriptionSubtitle.innerHTML = localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."); reset(descriptionSubtitle, localize('performanceIssueDesciption', "When did this performance issue happen? Does it occur on startup or after a specific series of actions? We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
} else if (issueType === IssueType.FeatureRequest) { } else if (issueType === IssueType.FeatureRequest) {
descriptionTitle.innerHTML = `${localize('description', "Description")} <span class="required-input">*</span>`; reset(descriptionTitle, localize('description', "Description"), $('span.required-input', undefined, '*'));
descriptionSubtitle.innerHTML = localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."); reset(descriptionSubtitle, localize('featureRequestDescription', "Please describe the feature you would like to see. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
show(problemSource); show(problemSource);
if (fileOnExtension) { if (fileOnExtension) {
@@ -805,8 +796,8 @@ export class IssueReporter extends Disposable {
show(searchedExtensionsBlock); show(searchedExtensionsBlock);
show(settingsSearchResultsBlock); show(settingsSearchResultsBlock);
descriptionTitle.innerHTML = `${localize('expectedResults', "Expected Results")} <span class="required-input">*</span>`; reset(descriptionTitle, localize('expectedResults', "Expected Results"), $('span.required-input', undefined, '*'));
descriptionSubtitle.innerHTML = localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."); reset(descriptionSubtitle, localize('settingsSearchResultsDescription', "Please list the results that you were expecting to see when you searched with this query. We support GitHub-flavored Markdown. You will be able to edit your issue and add screenshots when we preview it on GitHub."));
} }
} }
@@ -928,42 +919,82 @@ export class IssueReporter extends Disposable {
} }
private updateSystemInfo(state: IssueReporterModelData) { private updateSystemInfo(state: IssueReporterModelData) {
const target = document.querySelector('.block-system .block-info'); const target = document.querySelector<HTMLElement>('.block-system .block-info');
if (target) { if (target) {
const systemInfo = state.systemInfo!; const systemInfo = state.systemInfo!;
let renderedData = ` const renderedDataTable = $('table', undefined,
<table> $('tr', undefined,
<tr><td>CPUs</td><td>${systemInfo.cpus}</td></tr> $('td', undefined, 'CPUs'),
<tr><td>GPU Status</td><td>${Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('<br>')}</td></tr> $('td', undefined, systemInfo.cpus || ''),
<tr><td>Load (avg)</td><td>${systemInfo.load}</td></tr> ),
<tr><td>Memory (System)</td><td>${systemInfo.memory}</td></tr> $('tr', undefined,
<tr><td>Process Argv</td><td>${systemInfo.processArgs}</td></tr> $('td', undefined, 'GPU Status' as string),
<tr><td>Screen Reader</td><td>${systemInfo.screenReader}</td></tr> $('td', undefined, Object.keys(systemInfo.gpuStatus).map(key => `${key}: ${systemInfo.gpuStatus[key]}`).join('\n')),
<tr><td>VM</td><td>${systemInfo.vmHint}</td></tr> ),
</table>`; $('tr', undefined,
$('td', undefined, 'Load (avg)' as string),
$('td', undefined, systemInfo.load || ''),
),
$('tr', undefined,
$('td', undefined, 'Memory (System)' as string),
$('td', undefined, systemInfo.memory),
),
$('tr', undefined,
$('td', undefined, 'Process Argv' as string),
$('td', undefined, systemInfo.processArgs),
),
$('tr', undefined,
$('td', undefined, 'Screen Reader' as string),
$('td', undefined, systemInfo.screenReader),
),
$('tr', undefined,
$('td', undefined, 'VM'),
$('td', undefined, systemInfo.vmHint),
),
);
reset(target, renderedDataTable);
systemInfo.remoteData.forEach(remote => { systemInfo.remoteData.forEach(remote => {
target.appendChild($<HTMLHRElement>('hr'));
if (isRemoteDiagnosticError(remote)) { if (isRemoteDiagnosticError(remote)) {
renderedData += ` const remoteDataTable = $('table', undefined,
<hr> $('tr', undefined,
<table> $('td', undefined, 'Remote'),
<tr><td>Remote</td><td>${remote.hostName}</td></tr> $('td', undefined, remote.hostName)
<tr><td></td><td>${remote.errorMessage}</td></tr> ),
</table>`; $('tr', undefined,
$('td', undefined, ''),
$('td', undefined, remote.errorMessage)
)
);
target.appendChild(remoteDataTable);
} else { } else {
renderedData += ` const remoteDataTable = $('table', undefined,
<hr> $('tr', undefined,
<table> $('td', undefined, 'Remote'),
<tr><td>Remote</td><td>${remote.hostName}</td></tr> $('td', undefined, remote.hostName)
<tr><td>OS</td><td>${remote.machineInfo.os}</td></tr> ),
<tr><td>CPUs</td><td>${remote.machineInfo.cpus}</td></tr> $('tr', undefined,
<tr><td>Memory (System)</td><td>${remote.machineInfo.memory}</td></tr> $('td', undefined, 'OS'),
<tr><td>VM</td><td>${remote.machineInfo.vmHint}</td></tr> $('td', undefined, remote.machineInfo.os)
</table>`; ),
$('tr', undefined,
$('td', undefined, 'CPUs'),
$('td', undefined, remote.machineInfo.cpus || '')
),
$('tr', undefined,
$('td', undefined, 'Memory (System)' as string),
$('td', undefined, remote.machineInfo.memory)
),
$('tr', undefined,
$('td', undefined, 'VM'),
$('td', undefined, remote.machineInfo.vmHint)
),
);
target.appendChild(remoteDataTable);
} }
}); });
target.innerHTML = renderedData;
} }
} }
@@ -995,15 +1026,18 @@ export class IssueReporter extends Disposable {
return 0; return 0;
}); });
const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData) => { const makeOption = (extension: IOption, selectedExtension?: IssueReporterExtensionData): HTMLOptionElement => {
const selected = selectedExtension && extension.id === selectedExtension.id; const selected = selectedExtension && extension.id === selectedExtension.id;
return `<option value="${extension.id}" ${selected ? 'selected' : ''}>${escape(extension.name)}</option>`; return $<HTMLOptionElement>('option', {
'value': extension.id,
'selected': selected || ''
}, extension.name);
}; };
const extensionsSelector = this.getElementById('extension-selector'); const extensionsSelector = this.getElementById('extension-selector');
if (extensionsSelector) { if (extensionsSelector) {
const { selectedExtension } = this.issueReporterModel.getData(); const { selectedExtension } = this.issueReporterModel.getData();
extensionsSelector.innerHTML = '<option></option>' + extensionOptions.map(extension => makeOption(extension, selectedExtension)).join('\n'); reset(extensionsSelector, $<HTMLOptionElement>('option'), ...extensionOptions.map(extension => makeOption(extension, selectedExtension)));
this.addEventListener('extension-selector', 'change', (e: Event) => { this.addEventListener('extension-selector', 'change', (e: Event) => {
const selectedExtensionId = (<HTMLInputElement>e.target).value; const selectedExtensionId = (<HTMLInputElement>e.target).value;
@@ -1071,9 +1105,9 @@ export class IssueReporter extends Disposable {
} }
private updateProcessInfo(state: IssueReporterModelData) { private updateProcessInfo(state: IssueReporterModelData) {
const target = document.querySelector('.block-process .block-info'); const target = document.querySelector('.block-process .block-info') as HTMLElement;
if (target) { if (target) {
target.innerHTML = `<code>${state.processInfo}</code>`; reset(target, $('code', undefined, state.processInfo));
} }
} }
@@ -1085,7 +1119,7 @@ export class IssueReporter extends Disposable {
const target = document.querySelector<HTMLElement>('.block-extensions .block-info'); const target = document.querySelector<HTMLElement>('.block-extensions .block-info');
if (target) { if (target) {
if (this.configuration.disableExtensions) { if (this.configuration.disableExtensions) {
target.innerHTML = localize('disabledExtensions', "Extensions are disabled"); reset(target, localize('disabledExtensions', "Extensions are disabled"));
return; return;
} }
@@ -1097,8 +1131,7 @@ export class IssueReporter extends Disposable {
return; return;
} }
const table = this.getExtensionTableHtml(extensions); reset(target, this.getExtensionTableHtml(extensions), document.createTextNode(themeExclusionStr));
target.innerHTML = `<table>${table}</table>${themeExclusionStr}`;
} }
} }
@@ -1111,28 +1144,24 @@ export class IssueReporter extends Disposable {
} }
const table = this.getExtensionTableHtml(extensions); const table = this.getExtensionTableHtml(extensions);
target.innerHTML = `<table>${table}</table>`; target.innerText = '';
target.appendChild(table);
} }
} }
private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): string { private getExtensionTableHtml(extensions: IssueReporterExtensionData[]): HTMLTableElement {
let table = ` return $('table', undefined,
<tr> $('tr', undefined,
<th>Extension</th> $('th', undefined, 'Extension'),
<th>Author (truncated)</th> $('th', undefined, 'Author (truncated)' as string),
<th>Version</th> $('th', undefined, 'Version'),
</tr>`; ),
...extensions.map(extension => $('tr', undefined,
table += extensions.map(extension => { $('td', undefined, extension.name),
return ` $('td', undefined, extension.publisher.substr(0, 3)),
<tr> $('td', undefined, extension.version),
<td>${extension.name}</td> ))
<td>${extension.publisher.substr(0, 3)}</td> );
<td>${extension.version}</td>
</tr>`;
}).join('');
return table;
} }
private openLink(event: MouseEvent): void { private openLink(event: MouseEvent): void {

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M6 4v8l4-4-4-4zm1 2.414L8.586 8 7 9.586V6.414z"/></svg>

Before

Width:  |  Height:  |  Size: 139 B

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#646465" d="M11 10H5.344L11 4.414V10z"/></svg>

Before

Width:  |  Height:  |  Size: 118 B

View File

@@ -58,6 +58,7 @@ table {
width: 100%; width: 100%;
table-layout: fixed; table-layout: fixed;
} }
th[scope='col'] { th[scope='col'] {
vertical-align: bottom; vertical-align: bottom;
border-bottom: 1px solid #cccccc; border-bottom: 1px solid #cccccc;
@@ -65,6 +66,7 @@ th[scope='col'] {
border-top: 1px solid #cccccc; border-top: 1px solid #cccccc;
cursor: default; cursor: default;
} }
td { td {
padding: .25rem; padding: .25rem;
vertical-align: top; vertical-align: top;
@@ -100,7 +102,6 @@ tbody > tr:hover {
display: none; display: none;
} }
img { .header {
width: 16px; display: flex;
margin-right: 4px;
} }

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/processExplorer'; import 'vs/css!./media/processExplorer';
import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron'; import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals'; import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
import { localize } from 'vs/nls'; import { localize } from 'vs/nls';
@@ -16,6 +17,7 @@ import { addDisposableListener, addClass } from 'vs/base/browser/dom';
import { DisposableStore } from 'vs/base/common/lifecycle'; import { DisposableStore } from 'vs/base/common/lifecycle';
import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; import { isRemoteDiagnosticError, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
import { MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService'; import { MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/; const DEBUG_FLAGS_PATTERN = /\s--(inspect|debug)(-brk|port)?=(\d+)?/;
const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/; const DEBUG_PORT_PATTERN = /\s--(inspect|debug)-port=(\d+)/;
@@ -156,15 +158,15 @@ class ProcessExplorer {
return maxProcessId; return maxProcessId;
} }
private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: HTMLImageElement, sectionName: string) { private updateSectionCollapsedState(shouldExpand: boolean, body: HTMLElement, twistie: CodiconLabel, sectionName: string) {
if (shouldExpand) { if (shouldExpand) {
body.classList.remove('hidden'); body.classList.remove('hidden');
this.collapsedStateCache.set(sectionName, false); this.collapsedStateCache.set(sectionName, false);
twistie.src = './media/expanded.svg'; twistie.text = '$(chevron-down)';
} else { } else {
body.classList.add('hidden'); body.classList.add('hidden');
this.collapsedStateCache.set(sectionName, true); this.collapsedStateCache.set(sectionName, true);
twistie.src = './media/collapsed.svg'; twistie.text = '$(chevron-right)';
} }
} }
@@ -191,18 +193,27 @@ class ProcessExplorer {
private renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) { private renderProcessGroupHeader(sectionName: string, body: HTMLElement, container: HTMLElement) {
const headerRow = document.createElement('tr'); const headerRow = document.createElement('tr');
const data = document.createElement('td');
data.textContent = sectionName;
data.colSpan = 4;
headerRow.appendChild(data);
const twistie = document.createElement('img'); const headerData = document.createElement('td');
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistie, sectionName); headerData.colSpan = 4;
data.prepend(twistie); headerRow.appendChild(headerData);
this.listeners.add(addDisposableListener(data, 'click', (e) => { const headerContainer = document.createElement('div');
headerContainer.className = 'header';
headerData.appendChild(headerContainer);
const twistieContainer = document.createElement('div');
const twistieCodicon = new CodiconLabel(twistieContainer);
this.updateSectionCollapsedState(!this.collapsedStateCache.get(sectionName), body, twistieCodicon, sectionName);
headerContainer.appendChild(twistieContainer);
const headerLabel = document.createElement('span');
headerLabel.textContent = sectionName;
headerContainer.appendChild(headerLabel);
this.listeners.add(addDisposableListener(headerData, 'click', (e) => {
const isHidden = body.classList.contains('hidden'); const isHidden = body.classList.contains('hidden');
this.updateSectionCollapsedState(isHidden, body, twistie, sectionName); this.updateSectionCollapsedState(isHidden, body, twistieCodicon, sectionName);
})); }));
container.appendChild(headerRow); container.appendChild(headerRow);

View File

@@ -0,0 +1,18 @@
<!-- Copyright (C) Microsoft Corporation. All rights reserved. -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote-resource:; media-src 'none'; frame-src 'self' vscode-webview: https://*.vscode-webview-test.com; object-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' https:; font-src 'self' https: vscode-remote-resource:;">
</head>
<body aria-label="">
</body>
<!-- Init Bootstrap Helpers -->
<script src="../../../../bootstrap.js"></script>
<script src="../../../../vs/loader.js"></script>
<script src="../../../../bootstrap-window.js"></script>
<!-- Startup via workbench.js -->
<script src="workbench.js"></script>
</html>

View File

@@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/// <reference path="../../../../typings/require.d.ts" />
//@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;
},
beforeRequire: function () {
perf.mark('willLoadWorkbenchMain');
}
}
);

View File

@@ -14,7 +14,7 @@ import * as paths from 'vs/base/common/path';
import { whenDeleted, writeFileSync } from 'vs/base/node/pfs'; import { whenDeleted, writeFileSync } from 'vs/base/node/pfs';
import { findFreePort, randomPort } from 'vs/base/node/ports'; import { findFreePort, randomPort } from 'vs/base/node/ports';
import { isWindows, isLinux } from 'vs/base/common/platform'; import { isWindows, isLinux } from 'vs/base/common/platform';
import { ProfilingSession, Target } from 'v8-inspect-profiler'; import type { ProfilingSession, Target } from 'v8-inspect-profiler';
import { isString } from 'vs/base/common/types'; import { isString } from 'vs/base/common/types';
import { hasStdinWithoutTty, stdinDataListener, getStdinFilePath, readFromStdin } from 'vs/platform/environment/node/stdin'; import { hasStdinWithoutTty, stdinDataListener, getStdinFilePath, readFromStdin } from 'vs/platform/environment/node/stdin';

View File

@@ -7,7 +7,6 @@ import { localize } from 'vs/nls';
import { raceTimeout } from 'vs/base/common/async'; import { raceTimeout } from 'vs/base/common/async';
import product from 'vs/platform/product/common/product'; import product from 'vs/platform/product/common/product';
import * as path from 'vs/base/common/path'; import * as path from 'vs/base/common/path';
import * as semver from 'semver-umd';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -214,6 +213,8 @@ export class Main {
throw new Error('Invalid vsix'); throw new Error('Invalid vsix');
} }
const semver = await import('semver-umd');
const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) }; const extensionIdentifier = { id: getGalleryExtensionId(manifest.publisher, manifest.name) };
const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User); const installedExtensions = await this.extensionManagementService.getInstalled(ExtensionType.User);
const newer = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier) && semver.gt(local.manifest.version, manifest.version)); const newer = installedExtensions.find(local => areSameExtensions(extensionIdentifier, local.identifier) && semver.gt(local.manifest.version, manifest.version));

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information. * Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as cp from 'child_process'; import { spawn } from 'child_process';
import { generateUuid } from 'vs/base/common/uuid'; import { generateUuid } from 'vs/base/common/uuid';
import { isWindows } from 'vs/base/common/platform'; import { isWindows } from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log'; import { ILogService } from 'vs/platform/log/common/log';
@@ -30,7 +30,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
logService.trace('getUnixShellEnvironment#env', env); logService.trace('getUnixShellEnvironment#env', env);
logService.trace('getUnixShellEnvironment#spawn', command); logService.trace('getUnixShellEnvironment#spawn', command);
const child = cp.spawn(process.env.SHELL!, ['-ilc', command], { const child = spawn(process.env.SHELL!, ['-ilc', command], {
detached: true, detached: true,
stdio: ['ignore', 'pipe', process.stderr], stdio: ['ignore', 'pipe', process.stderr],
env env
@@ -82,8 +82,7 @@ function getUnixShellEnvironment(logService: ILogService): Promise<typeof proces
return promise.catch(() => ({})); return promise.catch(() => ({}));
} }
let shellEnvPromise: Promise<typeof process.env> | undefined = undefined;
let _shellEnv: Promise<typeof process.env>;
/** /**
* We need to get the environment from a user's shell. * We need to get the environment from a user's shell.
@@ -91,21 +90,21 @@ let _shellEnv: Promise<typeof process.env>;
* from within a shell. * from within a shell.
*/ */
export function getShellEnvironment(logService: ILogService, environmentService: INativeEnvironmentService): Promise<typeof process.env> { export function getShellEnvironment(logService: ILogService, environmentService: INativeEnvironmentService): Promise<typeof process.env> {
if (_shellEnv === undefined) { if (!shellEnvPromise) {
if (environmentService.args['disable-user-env-probe']) { if (environmentService.args['disable-user-env-probe']) {
logService.trace('getShellEnvironment: disable-user-env-probe set, skipping'); logService.trace('getShellEnvironment: disable-user-env-probe set, skipping');
_shellEnv = Promise.resolve({}); shellEnvPromise = Promise.resolve({});
} else if (isWindows) { } else if (isWindows) {
logService.trace('getShellEnvironment: running on Windows, skipping'); logService.trace('getShellEnvironment: running on Windows, skipping');
_shellEnv = Promise.resolve({}); shellEnvPromise = Promise.resolve({});
} else if (process.env['VSCODE_CLI'] === '1' && process.env['VSCODE_FORCE_USER_ENV'] !== '1') { } else if (process.env['VSCODE_CLI'] === '1' && process.env['VSCODE_FORCE_USER_ENV'] !== '1') {
logService.trace('getShellEnvironment: running on CLI, skipping'); logService.trace('getShellEnvironment: running on CLI, skipping');
_shellEnv = Promise.resolve({}); shellEnvPromise = Promise.resolve({});
} else { } else {
logService.trace('getShellEnvironment: running on Unix'); logService.trace('getShellEnvironment: running on Unix');
_shellEnv = getUnixShellEnvironment(logService); shellEnvPromise = getUnixShellEnvironment(logService);
} }
} }
return _shellEnv; return shellEnvPromise;
} }

View File

@@ -28,9 +28,8 @@ suite('Windows Native Helpers', () => {
}); });
test('vscode-windows-ca-certs', async () => { test('vscode-windows-ca-certs', async () => {
const windowsCerts = await new Promise<any>((resolve, reject) => { // @ts-ignore Windows only
require(['vscode-windows-ca-certs'], resolve, reject); const windowsCerts = await import('vscode-windows-ca-certs');
});
assert.ok(windowsCerts, 'Unable to load vscode-windows-ca-certs dependency.'); assert.ok(windowsCerts, 'Unable to load vscode-windows-ca-certs dependency.');
}); });

View File

@@ -72,7 +72,7 @@ interface InMemoryClipboardMetadata {
* Every time we read from the cipboard, if the text matches our last written text, * Every time we read from the cipboard, if the text matches our last written text,
* we can fetch the previous metadata. * we can fetch the previous metadata.
*/ */
class InMemoryClipboardMetadataManager { export class InMemoryClipboardMetadataManager {
public static readonly INSTANCE = new InMemoryClipboardMetadataManager(); public static readonly INSTANCE = new InMemoryClipboardMetadataManager();
private _lastState: InMemoryClipboardMetadata | null; private _lastState: InMemoryClipboardMetadata | null;

Some files were not shown because too many files have changed in this diff Show More