Merge remote-tracking branch 'origin/master' into tyriar/virtual_process

This commit is contained in:
Daniel Imms 2019-07-02 08:48:43 -07:00
commit c5853f3aba
98 changed files with 1033 additions and 701 deletions

View file

@ -59,6 +59,5 @@
"git.ignoreLimitWarning": true,
"remote.extensionKind": {
"msjsdiag.debugger-for-chrome": "workspace"
},
"typescript.experimental.useSeparateSyntaxServer": true
}
}

View file

@ -83,13 +83,13 @@ node-pty/deps/**
!node-pty/build/Release/*.dll
!node-pty/build/Release/*.node
vscode-nsfw/binding.gyp
vscode-nsfw/build/**
vscode-nsfw/src/**
vscode-nsfw/openpa/**
vscode-nsfw/includes/**
!vscode-nsfw/build/Release/*.node
!vscode-nsfw/**/*.a
nsfw/binding.gyp
nsfw/build/**
nsfw/src/**
nsfw/openpa/**
nsfw/includes/**
!nsfw/build/Release/*.node
!nsfw/**/*.a
vsda/binding.gyp
vsda/README.md

View file

@ -30,7 +30,13 @@ steps:
git remote add distro "https://github.com/$VSCODE_MIXIN_REPO.git"
git fetch distro
git push distro origin/master:refs/heads/master
# Push master branch into master and oss/master
git push distro origin/master:refs/heads/master origin/master:refs/heads/oss/master
# Push every release branch into oss/release
git for-each-ref --format="%(refname:short)" refs/remotes/origin/release/* | sed 's/^origin\/\(.*\)$/\0:refs\/heads\/oss\/\1/' | xargs git push distro
git merge $(node -p "require('./package.json').distro")
displayName: Sync & Merge Distro

View file

@ -85,7 +85,7 @@ jobs:
- template: darwin/product-build-darwin.yml
- job: Release
condition: and(succeeded(), or(eq(variables['VSCODE_RELEASE'], 'true'), and(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['Build.Reason'], 'Schedule')), and(eq(variables['VSCODE_QUALITY'], 'exploration'), eq(variables['Build.SourceBranch'], 'refs/heads/electron-6.0.x'))))
condition: and(succeeded(), or(eq(variables['VSCODE_RELEASE'], 'true'), and(or(eq(variables['VSCODE_QUALITY'], 'insider'), eq(variables['VSCODE_QUALITY'], 'exploration')), eq(variables['Build.Reason'], 'Schedule'))))
pool:
vmImage: 'Ubuntu-16.04'
dependsOn:
@ -112,4 +112,11 @@ jobs:
- LinuxAlpine
- macOS
steps:
- template: sync-mooncake.yml
- template: sync-mooncake.yml
schedules:
- cron: "0 6 * * Mon-Fri"
displayName: Mon-Fri at 6:00
branches:
include:
- master

View file

@ -0,0 +1,18 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const cp = require('child_process');
const path = require('path');
const fs = require('fs');
const rootPath = path.dirname(path.dirname(path.dirname(__dirname)));
const vscodePath = path.join(rootPath, 'vscode');
const distroPath = path.join(rootPath, 'vscode-distro');
const commit = cp.execSync('git rev-parse HEAD', { cwd: distroPath, encoding: 'utf8' }).trim();
const packageJsonPath = path.join(vscodePath, 'package.json');
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
packageJson.distro = commit;
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/9c4f4b3291538d9f5144f02d3b6af877b84f2cb2",
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/19ef66475b6bb21b5ed466cbcf8cef4e1b1fa212",
"name": "C++",
"scopeName": "source.cpp",
"patterns": [
@ -57,6 +57,9 @@
},
"ever_present_context": {
"patterns": [
{
"include": "#single_line_macro"
},
{
"include": "#preprocessor_rule_enabled"
},
@ -11193,6 +11196,58 @@
"match": "(?<!\\w)#(?:endif|else|elif)(?!\\w)",
"name": "keyword.control.directive.$0.cpp"
},
"single_line_macro": {
"match": "^((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))#define.*(?<![\\\\])(?:\\n|$)",
"captures": {
"0": {
"patterns": [
{
"include": "#meta_preprocessor_macro"
},
{
"include": "#comments"
},
{
"include": "#string_context"
},
{
"include": "#number_literal"
},
{
"include": "#operators"
},
{
"include": "#semicolon"
}
]
},
"1": {
"patterns": [
{
"include": "#inline_comment"
}
]
},
"2": {
"name": "comment.block.cpp punctuation.definition.comment.begin.cpp"
},
"3": {
"name": "comment.block.cpp"
},
"4": {
"patterns": [
{
"match": "\\*\\/",
"name": "comment.block.cpp punctuation.definition.comment.end.cpp"
},
{
"match": "\\*",
"name": "comment.block.cpp"
}
]
}
}
},
"assembly": {
"name": "meta.asm.cpp",
"begin": "(\\b(?:__asm__|asm)\\b)\\s*((?:volatile)?)\\s*(\\()",

View file

@ -2,6 +2,8 @@
#include <iostream>
using namespace std;
#define EXTERN_C extern "C"
class Rectangle {
int width, height;
public:

View file

@ -153,6 +153,116 @@
"hc_black": "default: #FFFFFF"
}
},
{
"c": "#",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"hc_black": "keyword.control: #C586C0"
}
},
{
"c": "define",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
"dark_vs": "keyword.control: #569CD6",
"light_vs": "keyword.control: #0000FF",
"hc_black": "keyword.control: #C586C0"
}
},
{
"c": " ",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
"dark_vs": "meta.preprocessor: #569CD6",
"light_vs": "meta.preprocessor: #0000FF",
"hc_black": "meta.preprocessor: #569CD6"
}
},
{
"c": "EXTERN_C",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
"light_plus": "entity.name.function: #795E26",
"dark_vs": "meta.preprocessor: #569CD6",
"light_vs": "meta.preprocessor: #0000FF",
"hc_black": "entity.name.function: #DCDCAA"
}
},
{
"c": " ",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
"dark_vs": "meta.preprocessor: #569CD6",
"light_vs": "meta.preprocessor: #0000FF",
"hc_black": "meta.preprocessor: #569CD6"
}
},
{
"c": "extern",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp storage.type.extern.cpp",
"r": {
"dark_plus": "storage.type: #569CD6",
"light_plus": "storage.type: #0000FF",
"dark_vs": "storage.type: #569CD6",
"light_vs": "storage.type: #0000FF",
"hc_black": "storage.type: #569CD6"
}
},
{
"c": " ",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp",
"r": {
"dark_plus": "meta.preprocessor: #569CD6",
"light_plus": "meta.preprocessor: #0000FF",
"dark_vs": "meta.preprocessor: #569CD6",
"light_vs": "meta.preprocessor: #0000FF",
"hc_black": "meta.preprocessor: #569CD6"
}
},
{
"c": "\"",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp punctuation.definition.string.begin.cpp",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178"
}
},
{
"c": "C",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178"
}
},
{
"c": "\"",
"t": "source.cpp source.cpp meta.preprocessor.macro.cpp meta.block.extern.cpp meta.head.extern.cpp string.quoted.double.cpp punctuation.definition.string.end.cpp",
"r": {
"dark_plus": "string: #CE9178",
"light_plus": "string: #A31515",
"dark_vs": "string: #CE9178",
"light_vs": "string: #A31515",
"hc_black": "string: #CE9178"
}
},
{
"c": "class",
"t": "source.cpp source.cpp meta.block.class.cpp meta.head.class.cpp storage.type.class.cpp",

View file

@ -225,7 +225,6 @@ export class MarkdownEngine {
return normalizeLink(externalSchemeUri.toString(true));
}
// Assume it must be an relative or absolute file path
// Use a fake scheme to avoid parse warnings
let uri = vscode.Uri.parse(`vscode-resource:${link}`);
@ -262,7 +261,7 @@ export class MarkdownEngine {
const validateLink = md.validateLink;
md.validateLink = (link: string) => {
// support file:// links
return validateLink(link) || link.indexOf('file:') === 0;
return validateLink(link) || link.startsWith('file:') || /^data:image\/.*?;/.test(link);
};
}

View file

@ -592,10 +592,10 @@
"description": "%configuration.surveys.enabled%",
"scope": "window"
},
"typescript.experimental.useSeparateSyntaxServer": {
"typescript.tsserver.useSeparateSyntaxServer": {
"type": "boolean",
"default": false,
"description": "%configuration.experimental.useSeparateSyntaxServer%",
"default": true,
"description": "%configuration.tsserver.useSeparateSyntaxServer%",
"scope": "window"
}
}
@ -758,4 +758,4 @@
}
]
}
}
}

View file

@ -49,7 +49,7 @@
"typescript.problemMatchers.tsc.label": "TypeScript problems",
"typescript.problemMatchers.tscWatch.label": "TypeScript problems (watch mode)",
"configuration.suggest.paths": "Enable/disable suggestions for paths in import statements and require calls.",
"configuration.experimental.useSeparateSyntaxServer": "Enable/disable spawning a separate TypeScript server that can more quickly respond to syntax related operations, such as calculating folding or computing document symbols. Requires using TypeScript 3.4.0 or newer in the workspace.",
"configuration.tsserver.useSeparateSyntaxServer": "Enable/disable spawning a separate TypeScript server that can more quickly respond to syntax related operations, such as calculating folding or computing document symbols. Requires using TypeScript 3.4.0 or newer in the workspace.",
"typescript.locale": "Sets the locale used to report JavaScript and TypeScript errors. Requires using TypeScript 2.6.0 or newer in the workspace. Default of `null` uses VS Code's locale.",
"javascript.implicitProjectConfig.experimentalDecorators": "Enable/disable `experimentalDecorators` for JavaScript files that are not part of a project. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.",
"configuration.suggest.autoImports": "Enable/disable auto import suggestions. Requires using TypeScript 2.6.1 or newer in the workspace.",

View file

@ -311,7 +311,10 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
this._register(syntaxServer.onEvent(e => this._onEvent.fire(e)));
this._register(semanticServer.onEvent(e => this._onEvent.fire(e)));
this._register(semanticServer.onExit(e => this._onExit.fire(e)));
this._register(semanticServer.onExit(e => {
this._onExit.fire(e);
this.syntaxServer.kill();
}));
this._register(semanticServer.onError(e => this._onError.fire(e)));
}

View file

@ -144,6 +144,6 @@ export class TypeScriptServiceConfiguration {
}
private static readUseSeparateSyntaxServer(configuration: vscode.WorkspaceConfiguration): boolean {
return configuration.get<boolean>('typescript.experimental.useSeparateSyntaxServer', false);
return configuration.get<boolean>('typescript.tsserver.useSeparateSyntaxServer', true);
}
}

View file

@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.37.0",
"distro": "2b36463d246567c8e51d136b5868513a8c866886",
"distro": "aeb8d17f84c592c5a508830f47aa1881dd35a156",
"author": {
"name": "Microsoft Corporation"
},
@ -24,7 +24,8 @@
"smoketest": "cd test/smoke && node test/index.js",
"download-builtin-extensions": "node build/lib/builtInExtensions.js",
"monaco-compile-check": "tsc -p src/tsconfig.monaco.json --noEmit",
"strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization"
"strict-initialization-watch": "tsc --watch -p src/tsconfig.json --noEmit --strictPropertyInitialization",
"update-distro": "node build/npm/update-distro.js"
},
"dependencies": {
"applicationinsights": "1.0.8",
@ -40,13 +41,13 @@
"native-keymap": "1.2.6",
"native-watchdog": "1.0.0",
"node-pty": "0.9.0-beta17",
"nsfw": "1.2.5",
"onigasm-umd": "^2.2.2",
"semver": "^5.5.0",
"spdlog": "^0.9.0",
"sudo-prompt": "8.2.0",
"v8-inspect-profiler": "^0.0.20",
"vscode-chokidar": "1.6.5",
"vscode-nsfw": "1.1.2",
"vscode-proxy-agent": "0.4.0",
"vscode-ripgrep": "^1.2.5",
"vscode-sqlite3": "4.0.7",
@ -155,4 +156,4 @@
"windows-mutex": "0.2.1",
"windows-process-tree": "0.2.3"
}
}
}

View file

@ -13,11 +13,11 @@
"minimist": "1.2.0",
"native-watchdog": "1.0.0",
"node-pty": "0.9.0-beta17",
"nsfw": "1.2.5",
"onigasm-umd": "^2.2.2",
"semver": "^5.5.0",
"spdlog": "^0.9.0",
"vscode-chokidar": "1.6.5",
"vscode-nsfw": "1.1.1",
"vscode-proxy-agent": "0.4.0",
"vscode-ripgrep": "^1.2.5",
"vscode-textmate": "^4.1.1",

View file

@ -379,11 +379,16 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
graceful-fs@4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
graceful-fs@4.1.11, graceful-fs@^4.1.2:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
graceful-fs@^4.1.6:
version "4.2.0"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.0.tgz#8d8fdc73977cb04104721cb53666c1ca64cd328b"
integrity sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -604,16 +609,16 @@ nan@2.8.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
integrity sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=
nan@^2.0.0, nan@^2.12.1, nan@^2.13.2, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nan@^2.10.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
integrity sha512-F4miItu2rGnV2ySkXOQoA8FKz/SR2Q2sWP0sbTxNxz/tuokeC8WxOhPMcwi0qIyGtVn/rrSeLbvVkznqCdwYnw==
nan@^2.12.1, nan@^2.13.2, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
native-watchdog@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/native-watchdog/-/native-watchdog-1.0.0.tgz#97344e83cd6815a8c8e6c44a52e7be05832e65ca"
@ -665,6 +670,16 @@ npmlog@^4.0.1:
gauge "~2.7.3"
set-blocking "~2.0.0"
nsfw@1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/nsfw/-/nsfw-1.2.5.tgz#febe581af616f7b042f89df133abe62416c4c803"
integrity sha512-m3mwZUKXiCR69PDMLfAmKmiNzy0Oe9LhFE0DYZC5cc1htNj5Hyb1sAgglXhuaDkibFy22AVvPC5cCFB3A6mYIw==
dependencies:
fs-extra "^7.0.0"
lodash.isinteger "^4.0.4"
lodash.isundefined "^3.0.1"
nan "^2.0.0"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
@ -1073,16 +1088,6 @@ vscode-fsevents@0.3.10:
dependencies:
nan "^2.10.0"
vscode-nsfw@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/vscode-nsfw/-/vscode-nsfw-1.1.1.tgz#7c3febe153677c5850b197a0b64a197cd11e95c7"
integrity sha512-Wg3vzN1U3T6P1uE13LdVVRIhdy7XWnWkwmAXhkLsIkH2QY0E/pvNDRLrwAMMW6GC1Fvvbxm3hzdIrCmr7Hq3FA==
dependencies:
fs-extra "^7.0.0"
lodash.isinteger "^4.0.4"
lodash.isundefined "^3.0.1"
nan "^2.10.0"
vscode-proxy-agent@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/vscode-proxy-agent/-/vscode-proxy-agent-0.4.0.tgz#574833e65405c6333f350f1b9fef9909deccb6b5"

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'vscode-nsfw' {
declare module 'nsfw' {
interface NsfwWatcher {
start(): any;
stop(): any;
@ -22,6 +22,7 @@ declare module 'vscode-nsfw' {
directory: string;
file?: string;
newFile?: string;
newDirectory?: string;
oldFile?: string;
}

View file

@ -7,13 +7,23 @@ import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { Event, Emitter } from 'vs/base/common/event';
export interface ITelemetryData {
from?: string;
target?: string;
readonly from?: string;
readonly target?: string;
[key: string]: any;
}
export interface IAction extends IDisposable {
export type WBActionExecutedClassification = {
id: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
from: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
export type WBActionExecutedEvent = {
id: string;
from: string;
};
export interface IAction extends IDisposable {
readonly id: string;
label: string;
tooltip: string;
class: string | undefined;
@ -25,12 +35,12 @@ export interface IAction extends IDisposable {
export interface IActionRunner extends IDisposable {
run(action: IAction, context?: any): Promise<any>;
onDidRun: Event<IRunEvent>;
onDidBeforeRun: Event<IRunEvent>;
readonly onDidRun: Event<IRunEvent>;
readonly onDidBeforeRun: Event<IRunEvent>;
}
export interface IActionViewItem extends IDisposable {
actionRunner: IActionRunner;
readonly actionRunner: IActionRunner;
setActionContext(context: any): void;
render(element: any /* HTMLElement */): void;
isEnabled(): boolean;
@ -39,12 +49,12 @@ export interface IActionViewItem extends IDisposable {
}
export interface IActionChangeEvent {
label?: string;
tooltip?: string;
class?: string;
enabled?: boolean;
checked?: boolean;
radio?: boolean;
readonly label?: string;
readonly tooltip?: string;
readonly class?: string;
readonly enabled?: boolean;
readonly checked?: boolean;
readonly radio?: boolean;
}
export class Action extends Disposable implements IAction {
@ -52,14 +62,14 @@ export class Action extends Disposable implements IAction {
protected _onDidChange = this._register(new Emitter<IActionChangeEvent>());
readonly onDidChange: Event<IActionChangeEvent> = this._onDidChange.event;
protected _id: string;
protected readonly _id: string;
protected _label: string;
protected _tooltip: string;
protected _cssClass: string | undefined;
protected _enabled: boolean;
protected _checked: boolean;
protected _radio: boolean;
protected _actionCallback?: (event?: any) => Promise<any>;
protected readonly _actionCallback?: (event?: any) => Promise<any>;
constructor(id: string, label: string = '', cssClass: string = '', enabled: boolean = true, actionCallback?: (event?: any) => Promise<any>) {
super();
@ -82,7 +92,7 @@ export class Action extends Disposable implements IAction {
this._setLabel(value);
}
protected _setLabel(value: string): void {
private _setLabel(value: string): void {
if (this._label !== value) {
this._label = value;
this._onDidChange.fire({ label: value });
@ -174,9 +184,9 @@ export class Action extends Disposable implements IAction {
}
export interface IRunEvent {
action: IAction;
result?: any;
error?: any;
readonly action: IAction;
readonly result?: any;
readonly error?: any;
}
export class ActionRunner extends Disposable implements IActionRunner {

View file

@ -23,7 +23,7 @@ function markTracked<T extends IDisposable>(x: T): void {
if (x && x !== Disposable.None) {
try {
x[__is_disposable_tracked__] = true;
(x as any)[__is_disposable_tracked__] = true;
} catch {
// noop
}
@ -37,7 +37,7 @@ function trackDisposable<T extends IDisposable>(x: T): T {
const stack = new Error().stack!;
setTimeout(() => {
if (!x[__is_disposable_tracked__]) {
if (!(x as any)[__is_disposable_tracked__]) {
console.log(stack);
}
}, 3000);

View file

@ -14,11 +14,11 @@ export function deepClone<T>(obj: T): T {
return obj as any;
}
const result: any = Array.isArray(obj) ? [] : {};
Object.keys(obj as any).forEach((key: string) => {
if (obj[key] && typeof obj[key] === 'object') {
result[key] = deepClone(obj[key]);
Object.keys(<any>obj).forEach((key: string) => {
if ((<any>obj)[key] && typeof (<any>obj)[key] === 'object') {
result[key] = deepClone((<any>obj)[key]);
} else {
result[key] = obj[key];
result[key] = (<any>obj)[key];
}
});
return result;

View file

@ -138,20 +138,6 @@ export async function readdir(path: string): Promise<string[]> {
return handleDirectoryChildren(await promisify(fs.readdir)(path));
}
export async function readdirWithFileTypes(path: string): Promise<fs.Dirent[]> {
const children = await promisify(fs.readdir)(path, { withFileTypes: true });
// Mac: uses NFD unicode form on disk, but we want NFC
// See also https://github.com/nodejs/node/issues/2165
if (platform.isMacintosh) {
for (const child of children) {
child.name = normalizeNFC(child.name);
}
}
return children;
}
export function readdirSync(path: string): string[] {
return handleDirectoryChildren(fs.readdirSync(path));
}
@ -479,12 +465,12 @@ function ensureWriteOptions(options?: IWriteFileOptions): IEnsuredWriteFileOptio
}
export async function readDirsInDir(dirPath: string): Promise<string[]> {
const children = await readdirWithFileTypes(dirPath);
const children = await readdir(dirPath);
const directories: string[] = [];
for (const child of children) {
if (child.isDirectory()) {
directories.push(child.name);
if (await dirExists(join(dirPath, child))) {
directories.push(child);
}
}

View file

@ -386,24 +386,6 @@ suite('PFS', () => {
}
});
test('readdirWithFileTypes', async () => {
if (canNormalize && typeof process.versions['electron'] !== 'undefined' /* needs electron */) {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'pfs', id, 'öäü');
await pfs.mkdirp(newDir, 493);
assert.ok(fs.existsSync(newDir));
const children = await pfs.readdirWithFileTypes(path.join(parentDir, 'pfs', id));
assert.equal(children.some(n => n.name === 'öäü'), true); // Mac always converts to NFD, so
assert.equal(children.some(n => n.isDirectory()), true);
await pfs.rimraf(parentDir);
}
});
test('writeFile (string)', async () => {
const smallData = 'Hello World';
const bigData = (new Array(100 * 1024)).join('Large String\n');

View file

@ -4,10 +4,10 @@
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<link rel="icon" href="/favicon.ico" type="image/x-icon" />
<!-- Disable pinch zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<meta http-equiv="Content-Security-Policy"
content="default-src 'none'; img-src 'self' https: data: blob: vscode-remote:; media-src 'none'; child-src 'self' {{WEBVIEW_ENDPOINT}}; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; connect-src 'self' ws: wss: https:; font-src 'self' blob: vscode-remote:;">

View file

@ -676,12 +676,14 @@ export class IssueReporter extends Disposable {
private logSearchError(error: Error) {
this.logService.warn('issueReporter#search ', error.message);
/* __GDPR__
"issueReporterSearchError" : {
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }
}
*/
this.telemetryService.publicLog('issueReporterSearchError', { message: error.message });
type IssueReporterSearchErrorClassification = {
message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' }
};
type IssueReporterSearchError = {
message: string;
};
this.telemetryService.publicLog2<IssueReporterSearchError, IssueReporterSearchErrorClassification>('issueReporterSearchError', { message: error.message });
}
private setUpTypes(): void {
@ -873,13 +875,15 @@ export class IssueReporter extends Disposable {
return false;
}
/* __GDPR__
"issueReporterSubmit" : {
"issueType" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"numSimilarIssuesDisplayed" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed });
type IssueReporterSubmitClassification = {
issueType: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
numSimilarIssuesDisplayed: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
};
type IssueReporterSubmitEvent = {
issueType: any;
numSimilarIssuesDisplayed: number;
};
this.telemetryService.publicLog2<IssueReporterSubmitEvent, IssueReporterSubmitClassification>('issueReporterSubmit', { issueType: this.issueReporterModel.getData().issueType, numSimilarIssuesDisplayed: this.numberOfSearchResultsDisplayed });
this.hasBeenSubmitted = true;
const baseUrl = this.getIssueUrlWithTitle((<HTMLInputElement>this.getElementById('issue-title')).value);
@ -1106,11 +1110,7 @@ export class IssueReporter extends Disposable {
// Exclude right click
if (event.which < 3) {
shell.openExternal((<HTMLAnchorElement>event.target).href);
/* __GDPR__
"issueReporterViewSimilarIssue" : { }
*/
this.telemetryService.publicLog('issueReporterViewSimilarIssue');
this.telemetryService.publicLog2('issueReporterViewSimilarIssue');
}
}
@ -1121,12 +1121,13 @@ export class IssueReporter extends Disposable {
} else {
const error = new Error(`${elementId} not found.`);
this.logService.error(error);
/* __GDPR__
"issueReporterGetElementError" : {
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }
}
*/
this.telemetryService.publicLog('issueReporterGetElementError', { message: error.message });
type IssueReporterGetElementErrorClassification = {
message: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
};
type IssueReporterGetElementErrorEvent = {
message: string;
};
this.telemetryService.publicLog2<IssueReporterGetElementErrorEvent, IssueReporterGetElementErrorClassification>('issueReporterGetElementError', { message: error.message });
return undefined;
}

View file

@ -138,12 +138,34 @@ export class CodeApplication extends Disposable {
//
// !!! DO NOT CHANGE without consulting the documentation !!!
//
app.on('remote-require', event => event.preventDefault());
app.on('remote-get-global', event => event.preventDefault());
app.on('remote-get-builtin', event => event.preventDefault());
app.on('remote-get-current-window', event => event.preventDefault());
app.on('remote-get-current-web-contents', event => event.preventDefault());
// app.on('remote-get-guest-web-contents', event => event.preventDefault()); // TODO@Ben TODO@Matt revisit this need for <webview>
app.on('remote-require', (event, sender, module) => {
this.logService.trace('App#on(remote-require): prevented');
event.preventDefault();
});
app.on('remote-get-global', (event, sender, module) => {
this.logService.trace(`App#on(remote-get-global): prevented on ${module}`);
event.preventDefault();
});
app.on('remote-get-builtin', (event, sender, module) => {
this.logService.trace(`App#on(remote-get-builtin): prevented on ${module}`);
if (module !== 'clipboard') {
event.preventDefault();
}
});
app.on('remote-get-current-window', event => {
this.logService.trace(`App#on(remote-get-current-window): prevented`);
event.preventDefault();
});
app.on('remote-get-current-web-contents', event => {
this.logService.trace(`App#on(remote-get-current-web-contents): prevented`);
event.preventDefault();
});
app.on('web-contents-created', (_event: Electron.Event, contents) => {
contents.on('will-attach-webview', (event: Electron.Event, webPreferences, params) => {

View file

@ -316,7 +316,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
const urls = ['https://marketplace.visualstudio.com/*', 'https://*.vsassets.io/*'];
this._win.webContents.session.webRequest.onBeforeSendHeaders({ urls }, (details, cb) => {
this.marketplaceHeadersPromise.then(headers => {
const requestHeaders = objects.assign(details.requestHeaders, headers);
const requestHeaders = objects.assign(details.requestHeaders, headers) as { [key: string]: string | undefined };
if (!this.configurationService.getValue('extensions.disableExperimentalAzureSearch')) {
requestHeaders['Cookie'] = `${requestHeaders['Cookie'] ? requestHeaders['Cookie'] + ';' : ''}EnableExternalSearchForVSCode=true`;
}
@ -340,12 +340,14 @@ export class CodeWindow extends Disposable implements ICodeWindow {
});
this._win.webContents.session.webRequest.onHeadersReceived(null!, (details, callback) => {
const contentType: string[] = (details.responseHeaders['content-type'] || details.responseHeaders['Content-Type']);
const responseHeaders = details.responseHeaders as { [key: string]: string[] };
const contentType: string[] = (responseHeaders['content-type'] || responseHeaders['Content-Type']);
if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) {
return callback({ cancel: true });
}
return callback({ cancel: false, responseHeaders: details.responseHeaders });
return callback({ cancel: false, responseHeaders });
});
// Remember that we loaded

View file

@ -1709,14 +1709,13 @@ export class WindowsManager extends Disposable implements IWindowsMainService {
private onWindowError(window: ICodeWindow, error: WindowError): void {
this.logService.error(error === WindowError.CRASHED ? '[VS Code]: render process crashed!' : '[VS Code]: detected unresponsive');
/* __GDPR__
"windowerror" : {
"type" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
this.telemetryService.publicLog('windowerror', { type: error });
type WindowErrorClassification = {
type: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
type WindowErrorEvent = {
type: WindowError;
};
this.telemetryService.publicLog2<WindowErrorEvent, WindowErrorClassification>('windowerror', { type: error });
// Unresponsive
if (error === WindowError.UNRESPONSIVE) {
if (window.isExtensionDevelopmentHost || window.isExtensionTestHost || (window.win && window.win.webContents && window.win.webContents.isDevToolsOpened())) {

View file

@ -17,18 +17,17 @@ import { ITheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/them
export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
private readonly _styleSheet: HTMLStyleElement;
private readonly _decorationOptionProviders: { [key: string]: IModelDecorationOptionsProvider };
private readonly _decorationOptionProviders = new Map<string, IModelDecorationOptionsProvider>();
private readonly _themeService: IThemeService;
constructor(@IThemeService themeService: IThemeService, styleSheet = dom.createStyleSheet()) {
super();
this._styleSheet = styleSheet;
this._decorationOptionProviders = Object.create(null);
this._themeService = themeService;
}
public registerDecorationType(key: string, options: IDecorationRenderOptions, parentTypeKey?: string): void {
let provider = this._decorationOptionProviders[key];
let provider = this._decorationOptionProviders.get(key);
if (!provider) {
const providerArgs: ProviderArguments = {
styleSheet: this._styleSheet,
@ -41,17 +40,17 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
} else {
provider = new DecorationSubTypeOptionsProvider(this._themeService, providerArgs);
}
this._decorationOptionProviders[key] = provider;
this._decorationOptionProviders.set(key, provider);
}
provider.refCount++;
}
public removeDecorationType(key: string): void {
const provider = this._decorationOptionProviders[key];
const provider = this._decorationOptionProviders.get(key);
if (provider) {
provider.refCount--;
if (provider.refCount <= 0) {
delete this._decorationOptionProviders[key];
this._decorationOptionProviders.delete(key);
provider.dispose();
this.listCodeEditors().forEach((ed) => ed.removeDecorations(key));
}
@ -59,7 +58,7 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
}
public resolveDecorationOptions(decorationTypeKey: string, writable: boolean): IModelDecorationOptions {
const provider = this._decorationOptionProviders[decorationTypeKey];
const provider = this._decorationOptionProviders.get(decorationTypeKey);
if (!provider) {
throw new Error('Unknown decoration type key: ' + decorationTypeKey);
}

View file

@ -36,7 +36,7 @@ export class ColorDetector extends Disposable implements IEditorContribution {
private _colorDatas = new Map<string, IColorData>();
private _colorDecoratorIds: string[] = [];
private readonly _decorationsTypes: { [key: string]: boolean } = {};
private readonly _decorationsTypes = new Set<string>();
private _isEnabled: boolean;
@ -180,7 +180,7 @@ export class ColorDetector extends Disposable implements IEditorContribution {
let color = `rgba(${rgba.r}, ${rgba.g}, ${rgba.b}, ${rgba.a})`;
let key = 'colorBox-' + subKey;
if (!this._decorationsTypes[key] && !newDecorationsTypes[key]) {
if (!this._decorationsTypes.has(key) && !newDecorationsTypes[key]) {
this._codeEditorService.registerDecorationType(key, {
before: {
contentText: ' ',
@ -210,11 +210,11 @@ export class ColorDetector extends Disposable implements IEditorContribution {
});
}
for (let subType in this._decorationsTypes) {
this._decorationsTypes.forEach(subType => {
if (!newDecorationsTypes[subType]) {
this._codeEditorService.removeDecorationType(subType);
}
}
});
this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, decorations);
}
@ -223,9 +223,9 @@ export class ColorDetector extends Disposable implements IEditorContribution {
this._decorationsIds = this._editor.deltaDecorations(this._decorationsIds, []);
this._colorDecoratorIds = this._editor.deltaDecorations(this._colorDecoratorIds, []);
for (let subType in this._decorationsTypes) {
this._decorationsTypes.forEach(subType => {
this._codeEditorService.removeDecorationType(subType);
}
});
}
getColorData(position: Position): IColorData | null {

View file

@ -14,7 +14,7 @@ import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { isSingleFolderWorkspaceIdentifier, toWorkspaceIdentifier, WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
export const KnownSnippetVariableNames = Object.freeze({
export const KnownSnippetVariableNames: { [key: string]: true } = Object.freeze({
'CURRENT_YEAR': true,
'CURRENT_YEAR_SHORT': true,
'CURRENT_MONTH': true,
@ -275,4 +275,4 @@ export class WorkspaceBasedVariableResolver implements VariableResolver {
}
return filename;
}
}
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><style>.icon-canvas-transparent{opacity:0;fill:#2d2d30}.icon-vs-out{fill:#2d2d30}.icon-vs-bg{fill:#c5c5c5}</style><path class="icon-canvas-transparent" d="M16 16H0V0h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 10c0 2.205-1.794 4-4 4-1.858 0-3.411-1.279-3.858-3h-.978l2.318 4H0v-1.703l2-3.408V0h11v6.142c1.721.447 3 2 3 3.858z" id="outline"/><path class="icon-vs-bg" d="M12 1v4.75A4.255 4.255 0 0 0 7.75 10h-.732L4.275 5.269 3 7.442V1h9zM7.747 14L4.269 8 .748 14h6.999zM15 10a3 3 0 1 1-6 0 3 3 0 0 1 6 0z" id="iconBg"/></svg>

After

Width:  |  Height:  |  Size: 594 B

View file

@ -90,7 +90,7 @@ export function createAndFillInActionBarActions(menu: IMenu, options: IMenuActio
return asDisposable(groups);
}
function asDisposable(groups: [string, Array<MenuItemAction | SubmenuItemAction>][]): IDisposable {
function asDisposable(groups: ReadonlyArray<[string, ReadonlyArray<MenuItemAction | SubmenuItemAction>]>): IDisposable {
const disposables = new DisposableStore();
for (const [, actions] of groups) {
for (const action of actions) {
@ -100,7 +100,7 @@ function asDisposable(groups: [string, Array<MenuItemAction | SubmenuItemAction>
return disposables;
}
function fillInActions(groups: [string, Array<MenuItemAction | SubmenuItemAction>][], target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, useAlternativeActions: boolean, isPrimaryGroup: (group: string) => boolean = group => group === 'navigation'): void {
function fillInActions(groups: ReadonlyArray<[string, ReadonlyArray<MenuItemAction | SubmenuItemAction>]>, target: IAction[] | { primary: IAction[]; secondary: IAction[]; }, useAlternativeActions: boolean, isPrimaryGroup: (group: string) => boolean = group => group === 'navigation'): void {
for (let tuple of groups) {
let [group, actions] = tuple;
if (useAlternativeActions) {

View file

@ -6,7 +6,7 @@
import 'vs/css!./contextMenuHandler';
import { IDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { ActionRunner, IRunEvent } from 'vs/base/common/actions';
import { ActionRunner, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Menu } from 'vs/base/browser/ui/menu/menu';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
@ -132,13 +132,7 @@ export class ContextMenuHandler {
private onActionRun(e: IRunEvent): void {
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'contextMenu' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'contextMenu' });
}
this.contextViewService.hideContextView(false);

View file

@ -647,21 +647,26 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
const message = getErrorMessage(err);
/* __GDPR__
"galleryService:requestError" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"cdn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"message": { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:requestError', { url, cdn: true, message });
/* __GDPR__
"galleryService:cdnFallback" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"message": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:cdnFallback', { url, message });
type GalleryServiceREClassification = {
url: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
cdn: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
message: { classification: 'CallstackOrException', purpose: 'FeatureInsight' };
};
type GalleryServiceREServiceEvent = {
url: string;
cdn: boolean;
message: string;
};
this.telemetryService.publicLog2<GalleryServiceREServiceEvent, GalleryServiceREClassification>('galleryService:requestError', { url, cdn: true, message });
type GalleryServiceCDNFBClassification = {
url: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
message: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
type GalleryServiceCDNFBEvent = {
url: string;
message: string;
};
this.telemetryService.publicLog2<GalleryServiceCDNFBEvent, GalleryServiceCDNFBClassification>('galleryService:cdnFallback', { url, message });
const fallbackOptions = assign({}, options, { url: fallbackUrl });
return this.requestService.request(fallbackOptions, token).then(undefined, err => {
@ -670,14 +675,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
}
const message = getErrorMessage(err);
/* __GDPR__
"galleryService:requestError" : {
"url" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"cdn": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"message": { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('galleryService:requestError', { url: fallbackUrl, cdn: false, message });
this.telemetryService.publicLog2<GalleryServiceREServiceEvent, GalleryServiceREClassification>('galleryService:requestError', { url: fallbackUrl, cdn: false, message });
return Promise.reject(err);
});
});

View file

@ -114,11 +114,11 @@ export interface ServiceIdentifier<T> {
}
function storeServiceDependency(id: Function, target: Function, index: number, optional: boolean): void {
if (target[_util.DI_TARGET] === target) {
target[_util.DI_DEPENDENCIES].push({ id, index, optional });
if ((target as any)[_util.DI_TARGET] === target) {
(target as any)[_util.DI_DEPENDENCIES].push({ id, index, optional });
} else {
target[_util.DI_DEPENDENCIES] = [{ id, index, optional }];
target[_util.DI_TARGET] = target;
(target as any)[_util.DI_DEPENDENCIES] = [{ id, index, optional }];
(target as any)[_util.DI_TARGET] = target;
}
}

View file

@ -16,6 +16,7 @@ import { IResolveResult, KeybindingResolver } from 'vs/platform/keybinding/commo
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
interface CurrentChord {
keypress: string;
@ -195,13 +196,7 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
} else {
this._commandService.executeCommand(resolveResult.commandId, resolveResult.commandArgs).then(undefined, err => this._notificationService.warn(err));
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._telemetryService.publicLog('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
this._telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: resolveResult.commandId, from: 'keybinding' });
}
return shouldPreventDefault;

View file

@ -21,6 +21,7 @@ import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSep
import { URI } from 'vs/base/common/uri';
import { IStateService } from 'vs/platform/state/common/state';
import { ILifecycleService } from 'vs/platform/lifecycle/electron-main/lifecycleMain';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
const telemetryFrom = 'menu';
@ -783,13 +784,7 @@ export class Menubar {
}
private reportMenuActionTelemetry(id: string): void {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id, from: telemetryFrom });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id, from: telemetryFrom });
}
private mnemonicLabel(label: string): string {

View file

@ -9,21 +9,16 @@ import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { safeStringify } from 'vs/base/common/objects';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
/* __GDPR__FRAGMENT__
"ErrorEvent" : {
"stack": { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"message" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"filename" : { "classification": "CustomerContent", "purpose": "PerformanceAndHealth" },
"callstack": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"msg" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"file" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"line": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"column": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"uncaught_error_name": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"uncaught_error_msg": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
"count": { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
type ErrorEventFragment = {
callstack: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
msg?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
file?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
line?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
column?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
uncaught_error_name?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
uncaught_error_msg?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth' };
count?: { classification: 'CallstackOrException', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
export interface ErrorEvent {
callstack: string;
msg?: string;
@ -124,12 +119,8 @@ export default abstract class BaseErrorTelemetry {
private _flushBuffer(): void {
for (let error of this._buffer) {
/* __GDPR__
"UnhandledError" : {
"${include}": [ "${ErrorEvent}" ]
}
*/
this._telemetryService.publicLog('UnhandledError', error, true);
type UnhandledErrorClassification = {} & ErrorEventFragment;
this._telemetryService.publicLog2<ErrorEvent, UnhandledErrorClassification>('UnhandledError', error, true);
}
this._buffer.length = 0;
}

View file

@ -23,4 +23,4 @@ export type StrictPropertyCheckError = 'Type of classified event does not match
export type StrictPropertyCheck<T extends IGDPRProperty, E> = StrictPropertyChecker<E, ClassifiedEvent<T>, StrictPropertyCheckError>;
export type GDPRClassification<T> = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined };
export type GDPRClassification<T> = { [_ in keyof T]: IPropertyData | IGDPRProperty | undefined };

View file

@ -57,12 +57,13 @@ export class TelemetryService implements ITelemetryService {
if (this._configurationService) {
this._updateUserOptIn();
this._configurationService.onDidChangeConfiguration(this._updateUserOptIn, this, this._disposables);
/* __GDPR__
"optInStatus" : {
"optIn" : { "classification": "SystemMetaData", "purpose": "BusinessInsight", "isMeasurement": true }
}
*/
this.publicLog('optInStatus', { optIn: this._userOptIn });
type OptInClass = {
optIn: { classification: 'SystemMetaData', purpose: 'BusinessInsight', isMeasurement: true };
};
type OptInEvent = {
optIn: boolean;
};
this.publicLog2<OptInEvent, OptInClass>('optInStatus', { optIn: this._userOptIn });
this._commonProperties.then(values => {
const isHashedId = /^[a-f0-9]+$/i.test(values['common.machineId']);

View file

@ -195,23 +195,27 @@ const configurationValueWhitelist = [
export function configurationTelemetry(telemetryService: ITelemetryService, configurationService: IConfigurationService): IDisposable {
return configurationService.onDidChangeConfiguration(event => {
if (event.source !== ConfigurationTarget.DEFAULT) {
/* __GDPR__
"updateConfiguration" : {
"configurationSource" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"configurationKeys": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateConfiguration', {
type UpdateConfigClassification = {
configurationSource: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
configurationKeys: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
type UpdateConfigEvent = {
configurationSource: string;
configurationKeys: string[];
};
telemetryService.publicLog2<UpdateConfigEvent, UpdateConfigClassification>('updateConfiguration', {
configurationSource: ConfigurationTargetToString(event.source),
configurationKeys: flattenKeys(event.sourceConfig)
});
/* __GDPR__
"updateConfigurationValues" : {
"configurationSource" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"configurationValues": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateConfigurationValues', {
type UpdateConfigValClassification = {
configurationSource: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
configurationValues: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
};
type UpdateConfigValEvent = {
configurationSource: string;
configurationValues: { [key: string]: any }[];
};
telemetryService.publicLog2<UpdateConfigValEvent, UpdateConfigValClassification>('updateConfigurationValues', {
configurationSource: ConfigurationTargetToString(event.source),
configurationValues: flattenValues(event.sourceConfig, configurationValueWhitelist)
});
@ -222,12 +226,13 @@ export function configurationTelemetry(telemetryService: ITelemetryService, conf
export function keybindingsTelemetry(telemetryService: ITelemetryService, keybindingService: IKeybindingService): IDisposable {
return keybindingService.onDidUpdateKeybindings(event => {
if (event.source === KeybindingSource.User && event.keybindings) {
/* __GDPR__
"updateKeybindings" : {
"bindings": { "classification": "CustomerContent", "purpose": "FeatureInsight" }
}
*/
telemetryService.publicLog('updateKeybindings', {
type UpdateKBClassification = {
bindings: { classification: 'CustomerContent', purpose: 'FeatureInsight' };
};
type UpdateKBEvents = {
bindings: { key: string, command: string, when: string | undefined, args: boolean | undefined }[];
};
telemetryService.publicLog2<UpdateKBEvents, UpdateKBClassification>('updateKeybindings', {
bindings: event.keybindings.map(binding => ({
key: binding.key,
command: binding.command,

View file

@ -206,15 +206,15 @@ export interface IFileToOpen {
}
export function isWorkspaceToOpen(uriToOpen: IURIToOpen): uriToOpen is IWorkspaceToOpen {
return !!uriToOpen['workspaceUri'];
return !!(uriToOpen as IWorkspaceToOpen)['workspaceUri'];
}
export function isFolderToOpen(uriToOpen: IURIToOpen): uriToOpen is IFolderToOpen {
return !!uriToOpen['folderUri'];
return !!(uriToOpen as IFolderToOpen)['folderUri'];
}
export function isFileToOpen(uriToOpen: IURIToOpen): uriToOpen is IFileToOpen {
return !!uriToOpen['fileUri'];
return !!(uriToOpen as IFileToOpen)['fileUri'];
}

View file

@ -337,11 +337,13 @@ export class WindowsService extends Disposable implements IWindowsService, IURLH
console[severity].apply(console, ...messages);
}
async showItemInFolder(path: URI): Promise<void> {
async showItemInFolder(resource: URI): Promise<void> {
this.logService.trace('windowsService#showItemInFolder');
if (path.scheme === Schemas.file) {
shell.showItemInFolder(path.fsPath);
if (resource.scheme === Schemas.file) {
shell.showItemInFolder(resource.fsPath);
} else if (resource.scheme === Schemas.userData) {
shell.showItemInFolder(resource.path);
}
}

45
src/vs/vscode.d.ts vendored
View file

@ -4754,24 +4754,24 @@ declare module 'vscode' {
* An array to which disposables can be added. When this
* extension is deactivated the disposables will be disposed.
*/
subscriptions: { dispose(): any }[];
readonly subscriptions: { dispose(): any }[];
/**
* A memento object that stores state in the context
* of the currently opened [workspace](#workspace.workspaceFolders).
*/
workspaceState: Memento;
readonly workspaceState: Memento;
/**
* A memento object that stores state independent
* of the current opened [workspace](#workspace.workspaceFolders).
*/
globalState: Memento;
readonly globalState: Memento;
/**
* The absolute file path of the directory containing the extension.
*/
extensionPath: string;
readonly extensionPath: string;
/**
* Get the absolute path of a resource contained in the extension.
@ -4789,7 +4789,7 @@ declare module 'vscode' {
* Use [`workspaceState`](#ExtensionContext.workspaceState) or
* [`globalState`](#ExtensionContext.globalState) to store key value data.
*/
storagePath: string | undefined;
readonly storagePath: string | undefined;
/**
* An absolute file path in which the extension can store global state.
@ -4798,14 +4798,14 @@ declare module 'vscode' {
*
* Use [`globalState`](#ExtensionContext.globalState) to store key value data.
*/
globalStoragePath: string;
readonly globalStoragePath: string;
/**
* An absolute file path of a directory in which the extension can create log files.
* The directory might not exist on disk and creation is up to the extension. However,
* the parent directory is guaranteed to be existent.
*/
logPath: string;
readonly logPath: string;
}
/**
@ -7539,6 +7539,37 @@ declare module 'vscode' {
*/
export const name: string | undefined;
/**
* The location of the workspace file, for example:
*
* `file:///Users/name/Development/myProject.code-workspace`
*
* or
*
* `untitled:1555503116870`
*
* for a workspace that is untitled and not yet saved.
*
* Depending on the workspace that is opened, the value will be:
* * `undefined` when no workspace or a single folder is opened
* * the path of the workspace file as `Uri` otherwise. if the workspace
* is untitled, the returned URI will use the `untitled:` scheme
*
* The location can e.g. be used with the `vscode.openFolder` command to
* open the workspace again after it has been closed.
*
* **Example:**
* ```typescript
* vscode.commands.executeCommand('vscode.openFolder', uriOfWorkspace);
* ```
*
* **Note:** it is not advised to use `workspace.workspaceFile` to write
* configuration data into the file. You can use `workspace.getConfiguration().update()`
* for that purpose which will work both when a single folder is opened as
* well as an untitled or saved workspace.
*/
export const workspaceFile: Uri | undefined;
/**
* An event that is emitted when a workspace folder is added or removed.
*/

View file

@ -1430,44 +1430,6 @@ declare module 'vscode' {
}
//#endregion
//#region Workspace URI Ben
export namespace workspace {
/**
* The location of the workspace file, for example:
*
* `file:///Users/name/Development/myProject.code-workspace`
*
* or
*
* `untitled:1555503116870`
*
* for a workspace that is untitled and not yet saved.
*
* Depending on the workspace that is opened, the value will be:
* * `undefined` when no workspace or a single folder is opened
* * the path of the workspace file as `Uri` otherwise. if the workspace
* is untitled, the returned URI will use the `untitled:` scheme
*
* The location can e.g. be used with the `vscode.openFolder` command to
* open the workspace again after it has been closed.
*
* **Example:**
* ```typescript
* vscode.commands.executeCommand('vscode.openFolder', uriOfWorkspace);
* ```
*
* **Note:** it is not advised to use `workspace.workspaceFile` to write
* configuration data into the file. You can use `workspace.getConfiguration().update()`
* for that purpose which will work both when a single folder is opened as
* well as an untitled or saved workspace.
*/
export const workspaceFile: Uri | undefined;
}
//#endregion
// #region Ben - status bar item with ID and Name
export namespace window {

View file

@ -174,13 +174,13 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
params[param].forEach((item: TransferQuickPickItems) => {
handlesToItems.set(item.handle, item);
});
input[param] = params[param];
(input as any)[param] = params[param];
} else if (param === 'activeItems' || param === 'selectedItems') {
input[param] = params[param]
(input as any)[param] = params[param]
.filter((handle: number) => handlesToItems.has(handle))
.map((handle: number) => handlesToItems.get(handle));
} else if (param === 'buttons') {
input[param] = params.buttons!.map(button => {
(input as any)[param] = params.buttons!.map(button => {
if (button.handle === -1) {
return this._quickInputService.backButton;
}
@ -195,7 +195,7 @@ export class MainThreadQuickOpen implements MainThreadQuickOpenShape {
};
});
} else {
input[param] = params[param];
(input as any)[param] = params[param];
}
}
return Promise.resolve(undefined);

View file

@ -425,6 +425,8 @@ export type TransferQuickInput = TransferQuickPick | TransferInputBox;
export interface BaseTransferQuickInput {
[key: string]: any;
id: number;
type?: 'quickPick' | 'inputBox';

View file

@ -44,14 +44,13 @@ export interface IExtensionAPI {
// _extensionAPIBrand: any;
}
/* __GDPR__FRAGMENT__
"ExtensionActivationTimes" : {
"startup": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"codeLoadingTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"activateCallTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true },
"activateResolvedTime" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth", "isMeasurement": true }
}
*/
export type ExtensionActivationTimesFragment = {
startup?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
codeLoadingTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
activateCallTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
activateResolvedTime?: { classification: 'SystemMetaData', purpose: 'PerformanceAndHealth', isMeasurement: true };
};
export class ExtensionActivationTimes {
public static readonly NONE = new ExtensionActivationTimes(false, -1, -1, -1);

View file

@ -458,14 +458,14 @@ function getLightIconUri(iconPath: QuickInputButton['iconPath']) {
|| iconPath instanceof URI) {
return getIconUri(iconPath);
}
return getIconUri(iconPath['light']);
return getIconUri((iconPath as any).light);
}
return undefined;
}
function getDarkIconUri(iconPath: QuickInputButton['iconPath']) {
if (iconPath && !(iconPath instanceof ThemeIcon) && iconPath['dark']) {
return getIconUri(iconPath['dark']);
if (iconPath && !(iconPath instanceof ThemeIcon) && (iconPath as any).dark) {
return getIconUri((iconPath as any).dark);
}
return undefined;
}

View file

@ -15,7 +15,7 @@ import { createApiFactory, IExtensionApiFactory } from 'vs/workbench/api/node/ex
import { NodeModuleRequireInterceptor, VSCodeNodeModuleFactory, KeytarNodeModuleFactory, OpenNodeModuleFactory } from 'vs/workbench/api/node/extHostRequireInterceptor';
import { ExtHostExtensionServiceShape, IEnvironment, IInitData, IMainContext, MainContext, MainThreadExtensionServiceShape, MainThreadTelemetryShape, MainThreadWorkspaceShape, IResolveAuthorityResult } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostConfiguration } from 'vs/workbench/api/common/extHostConfiguration';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ActivatedExtension, EmptyExtension, ExtensionActivatedByAPI, ExtensionActivatedByEvent, ExtensionActivationReason, ExtensionActivationTimes, ExtensionActivationTimesBuilder, ExtensionsActivator, IExtensionAPI, IExtensionContext, IExtensionModule, HostExtension, ExtensionActivationTimesFragment } from 'vs/workbench/api/common/extHostExtensionActivator';
import { ExtHostLogService } from 'vs/workbench/api/common/extHostLogService';
import { ExtHostStorage } from 'vs/workbench/api/common/extHostStorage';
import { ExtHostWorkspace } from 'vs/workbench/api/common/extHostWorkspace';
@ -51,6 +51,16 @@ export interface IHostUtils {
realpath(path: string): Promise<string>;
}
type TelemetryActivationEventFragment = {
id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
extensionVersion: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
activationEvents: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
reason: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
};
export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
private static readonly WORKSPACE_CONTAINS_TIMEOUT = 7000;
@ -313,23 +323,32 @@ export class ExtHostExtensionService implements ExtHostExtensionServiceShape {
"outcome" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._mainThreadTelemetryProxy.$publicLog('extensionActivationTimes', {
type ExtensionActivationTimesClassification = {
outcome: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
} & TelemetryActivationEventFragment & ExtensionActivationTimesFragment;
type ExtensionActivationTimesEvent = {
outcome: string
} & ActivationTimesEvent & TelemetryActivationEvent;
type ActivationTimesEvent = {
startup?: boolean;
codeLoadingTime?: number;
activateCallTime?: number;
activateResolvedTime?: number;
};
this._mainThreadTelemetryProxy.$publicLog2<ExtensionActivationTimesEvent, ExtensionActivationTimesClassification>('extensionActivationTimes', {
...event,
...(activationTimes || {}),
outcome,
outcome
});
}
private _doActivateExtension(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): Promise<ActivatedExtension> {
const event = getTelemetryActivationEvent(extensionDescription, reason);
/* __GDPR__
"activatePlugin" : {
"${include}": [
"${TelemetryActivationEvent}"
]
}
*/
this._mainThreadTelemetryProxy.$publicLog('activatePlugin', event);
type ActivatePluginClassification = {} & TelemetryActivationEventFragment;
this._mainThreadTelemetryProxy.$publicLog2<TelemetryActivationEvent, ActivatePluginClassification>('activatePlugin', event);
if (!extensionDescription.main) {
// Treat the extension as being empty => NOT AN ERROR CASE
return Promise.resolve(new EmptyExtension(ExtensionActivationTimes.NONE));
@ -736,22 +755,20 @@ function loadCommonJSModule<T>(logService: ILogService, modulePath: string, acti
return Promise.resolve(r);
}
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): any {
type TelemetryActivationEvent = {
id: string;
name: string;
extensionVersion: string;
publisherDisplayName: string;
activationEvents: string | null;
isBuiltin: boolean;
reason: string;
};
function getTelemetryActivationEvent(extensionDescription: IExtensionDescription, reason: ExtensionActivationReason): TelemetryActivationEvent {
const reasonStr = reason instanceof ExtensionActivatedByEvent ? reason.activationEvent :
reason instanceof ExtensionActivatedByAPI ? 'api' :
'';
/* __GDPR__FRAGMENT__
"TelemetryActivationEvent" : {
"id": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"extensionVersion": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"activationEvents": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"reason": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
const event = {
id: extensionDescription.identifier.value,
name: extensionDescription.name,

View file

@ -14,7 +14,7 @@ import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IActionViewItem, ActionsOrientation } from 'vs/base/browser/ui/actionbar/actionbar';
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
import { prepareActions } from 'vs/workbench/browser/actions';
import { IAction } from 'vs/base/common/actions';
import { IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Part, IPartOptions } from 'vs/workbench/browser/part';
import { Composite, CompositeRegistry } from 'vs/workbench/browser/composite';
import { IComposite } from 'vs/workbench/common/composite';
@ -23,7 +23,8 @@ import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/la
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IProgressIndicator } from 'vs/platform/progress/common/progress';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IProgressIndicator, IEditorProgressService } from 'vs/platform/progress/common/progress';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@ -168,15 +169,16 @@ export abstract class CompositePart<T extends Composite> extends Part {
// Instantiate composite from registry otherwise
const compositeDescriptor = this.registry.getComposite(id);
if (compositeDescriptor) {
const composite = compositeDescriptor.instantiate(this.instantiationService);
const compositeProgressIndicator = this.instantiationService.createInstance(CompositeProgressIndicator, this.progressBar, compositeDescriptor.id, isActive);
const compositeInstantiationService = this.instantiationService.createChild(new ServiceCollection(
[IEditorProgressService, compositeProgressIndicator] // provide the editor progress service for any editors instantiated within the composite
));
const composite = compositeDescriptor.instantiate(compositeInstantiationService);
const disposable = new DisposableStore();
// Remember as Instantiated
this.instantiatedCompositeItems.set(id, {
composite,
disposable,
progress: this._register(this.instantiationService.createInstance(CompositeProgressIndicator, this.progressBar, compositeDescriptor.id, isActive))
});
this.instantiatedCompositeItems.set(id, { composite, disposable, progress: compositeProgressIndicator });
// Register to title area update events from the composite
disposable.add(composite.onTitleAreaUpdate(() => this.onTitleAreaUpdate(composite.getId()), this));
@ -259,13 +261,7 @@ export abstract class CompositePart<T extends Composite> extends Part {
// Log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: this.nameForTelemetry });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: this.nameForTelemetry });
}
});

View file

@ -8,7 +8,7 @@ import { addDisposableListener, Dimension, EventType } from 'vs/base/browser/dom
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { ActionsOrientation, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IAction, IRunEvent } from 'vs/base/common/actions';
import { IAction, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import * as arrays from 'vs/base/common/arrays';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
import { dispose, DisposableStore } from 'vs/base/common/lifecycle';
@ -152,13 +152,7 @@ export abstract class TitleControl extends Themable {
// Log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'editorPart' });
}
}));
}

View file

@ -6,7 +6,7 @@
import 'vs/css!./media/notificationsActions';
import { INotificationViewItem } from 'vs/workbench/common/notifications';
import { localize } from 'vs/nls';
import { Action, IAction, ActionRunner } from 'vs/base/common/actions';
import { Action, IAction, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { CLEAR_NOTIFICATION, EXPAND_NOTIFICATION, COLLAPSE_NOTIFICATION, CLEAR_ALL_NOTIFICATIONS, HIDE_NOTIFICATIONS_CENTER } from 'vs/workbench/browser/parts/notifications/notificationsCommands';
@ -161,14 +161,7 @@ export class NotificationActionRunner extends ActionRunner {
}
protected async runAction(action: IAction, context: INotificationViewItem): Promise<any> {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'message' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: action.id, from: 'message' });
// Run and make sure to notify on any error again
try {

View file

@ -456,7 +456,7 @@ export class QuickInputList {
what = 'Last';
}
this.list['focus' + what]();
(this.list as any)['focus' + what]();
this.list.reveal(this.list.getFocus()[0]);
}

View file

@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom';
import { URI } from 'vs/base/common/uri';
import { IdGenerator } from 'vs/base/common/idGenerator';
const iconPathToClass = {};
const iconPathToClass: Record<string, string> = {};
const iconClassGenerator = new IdGenerator('quick-input-button-icon-');
export function getIconClass(iconPath: { dark: URI; light?: URI; } | undefined): string | undefined {

View file

@ -15,7 +15,7 @@ import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiat
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { StatusbarAlignment, IStatusbarService, IStatusbarEntry, IStatusbarEntryAccessor } from 'vs/platform/statusbar/common/statusbar';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector, ThemeColor } from 'vs/platform/theme/common/themeService';
import { STATUS_BAR_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_BACKGROUND, STATUS_BAR_ITEM_HOVER_BACKGROUND, STATUS_BAR_ITEM_ACTIVE_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_FOREGROUND, STATUS_BAR_PROMINENT_ITEM_BACKGROUND, STATUS_BAR_PROMINENT_ITEM_HOVER_BACKGROUND, STATUS_BAR_BORDER, STATUS_BAR_NO_FOLDER_FOREGROUND, STATUS_BAR_NO_FOLDER_BORDER } from 'vs/workbench/common/theme';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
@ -725,13 +725,7 @@ class StatusbarEntryItem extends Disposable {
activeTextEditorWidget.focus();
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id, from: 'status bar' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id, from: 'status bar' });
try {
await this.commandService.executeCommand(id, ...args);
} catch (error) {

View file

@ -59,7 +59,7 @@ export abstract class MenubarControl extends Disposable {
[index: string]: IMenu | undefined;
};
protected topLevelTitles = {
protected topLevelTitles: { [menu: string]: string } = {
'File': nls.localize({ key: 'mFile', comment: ['&& denotes a mnemonic'] }, "&&File"),
'Edit': nls.localize({ key: 'mEdit', comment: ['&& denotes a mnemonic'] }, "&&Edit"),
'Selection': nls.localize({ key: 'mSelection', comment: ['&& denotes a mnemonic'] }, "&&Selection"),
@ -407,9 +407,12 @@ export class NativeMenubarControl extends MenubarControl {
}
private getAdditionalKeybindings(): { [id: string]: IMenubarKeybinding } {
const keybindings = {};
const keybindings: { [id: string]: IMenubarKeybinding } = {};
if (isMacintosh) {
keybindings['workbench.action.quit'] = (this.getMenubarKeybinding('workbench.action.quit'));
const keybinding = this.getMenubarKeybinding('workbench.action.quit');
if (keybinding) {
keybindings['workbench.action.quit'] = keybinding;
}
}
return keybindings;

View file

@ -494,9 +494,9 @@ export class TitlebarPart extends Part implements ITitleService {
private onUpdateAppIconDragBehavior() {
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
if (setting) {
this.appIcon.style['-webkit-app-region'] = 'no-drag';
(this.appIcon.style as any)['-webkit-app-region'] = 'no-drag';
} else {
this.appIcon.style['-webkit-app-region'] = 'drag';
(this.appIcon.style as any)['-webkit-app-region'] = 'drag';
}
}

View file

@ -29,7 +29,6 @@ import { URI } from 'vs/base/common/uri';
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
import { ConfigurationCache } from 'vs/workbench/services/configuration/browser/configurationCache';
import { WebResources } from 'vs/workbench/browser/web.resources';
import { ISignService } from 'vs/platform/sign/common/sign';
import { SignService } from 'vs/platform/sign/browser/signService';
import { hash } from 'vs/base/common/hash';
@ -68,9 +67,6 @@ class CodeRendererMain extends Disposable {
// Layout
this._register(addDisposableListener(window, EventType.RESIZE, () => this.workbench.layout()));
// Resource Loading
this._register(new WebResources(<IFileService>services.serviceCollection.get(IFileService)));
// Workbench Lifecycle
this._register(this.workbench.onShutdown(() => this.dispose()));
@ -199,4 +195,4 @@ export function main(domElement: HTMLElement, options: IWorkbenchConstructionOpt
const renderer = new CodeRendererMain(domElement, options);
return renderer.open();
}
}

View file

@ -54,7 +54,6 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment';
import { ClassifiedEvent, StrictPropertyCheck, GDPRClassification } from 'vs/platform/telemetry/common/gdprTypings';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { toStoreData, restoreRecentlyOpened } from 'vs/platform/history/common/historyStorage';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
//#region Backup File
@ -758,13 +757,11 @@ export class SimpleWindowService extends Disposable implements IWindowService {
@IFileService private readonly fileService: IFileService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IStorageService private readonly storageService: IStorageService,
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService
@IWorkspaceContextService private readonly workspaceService: IWorkspaceContextService
) {
super();
this.addWorkspaceToRecentlyOpened();
this.restoreFullScreen();
this.registerListeners();
}
@ -780,12 +777,6 @@ export class SimpleWindowService extends Disposable implements IWindowService {
}
}
private restoreFullScreen(): void {
if (document.location.href.indexOf('&fullscreen=true') > 0) {
setTimeout(() => this.toggleFullScreen(this.layoutService.getWorkbenchElement()), 0);
}
}
private registerListeners(): void {
this._register(addDisposableListener(document, EventType.FULLSCREEN_CHANGE, () => {
if (document.fullscreenElement || (<any>document).webkitFullscreenElement) {
@ -962,7 +953,7 @@ export class SimpleWindowService extends Disposable implements IWindowService {
for (let i = 0; i < _uris.length; i++) {
const uri = _uris[i];
if ('folderUri' in uri) {
const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}&fullscreen=${!!browser.isFullscreen()}`;
const newAddress = `${document.location.origin}/?folder=${uri.folderUri.path}`;
if (openFolderInNewWindow) {
window.open(newAddress);
} else {
@ -970,7 +961,7 @@ export class SimpleWindowService extends Disposable implements IWindowService {
}
}
if ('workspaceUri' in uri) {
const newAddress = `${document.location.origin}/?workspace=${uri.workspaceUri.path}&fullscreen=${!!browser.isFullscreen()}`;
const newAddress = `${document.location.origin}/?workspace=${uri.workspaceUri.path}`;
if (openFolderInNewWindow) {
window.open(newAddress);
} else {

View file

@ -127,7 +127,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget
this._commentThreadContextValue = contextKeyService.createKey('commentThread', _commentThread.contextValue);
this._resizeObserver = null;
this._isExpanded = _commentThread.collapsibleState ? _commentThread.collapsibleState === modes.CommentThreadCollapsibleState.Expanded : undefined;
this._isExpanded = _commentThread.collapsibleState === modes.CommentThreadCollapsibleState.Expanded;
this._globalToDispose = [];
this._commentThreadDisposables = [];
this._submitActionsDisposables = [];

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="3 3 16 16" enable-background="new 3 3 16 16"><polygon fill="#e8e8e8" points="12.597,11.042 15.4,13.845 13.844,15.4 11.042,12.598 8.239,15.4 6.683,13.845 9.485,11.042 6.683,8.239 8.238,6.683 11.042,9.486 13.845,6.683 15.4,8.239"/></svg>

After

Width:  |  Height:  |  Size: 307 B

View file

@ -9,7 +9,7 @@ import * as browser from 'vs/base/browser/browser';
import * as dom from 'vs/base/browser/dom';
import * as arrays from 'vs/base/common/arrays';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
import { IAction, IRunEvent } from 'vs/base/common/actions';
import { IAction, IRunEvent, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
@ -31,6 +31,7 @@ import { createAndFillInActionBarActions, MenuEntryActionViewItem } from 'vs/pla
import { IMenu, IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { FocusSessionAction } from 'vs/workbench/contrib/debug/browser/debugActions';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
const DEBUG_TOOLBAR_POSITION_KEY = 'debug.actionswidgetposition';
const DEBUG_TOOLBAR_Y_KEY = 'debug.actionswidgety';
@ -54,6 +55,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
private activeActions: IAction[];
private updateScheduler: RunOnceScheduler;
private debugToolBarMenu: IMenu;
private disposeOnUpdate: IDisposable;
private isVisible: boolean;
private isBuilt: boolean;
@ -105,12 +107,17 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
return this.hide();
}
const actions = DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
const { actions, disposable } = DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
if (!arrays.equals(actions, this.activeActions, (first, second) => first.id === second.id)) {
this.actionBar.clear();
this.actionBar.push(actions, { icon: true, label: false });
this.activeActions = actions;
}
if (this.disposeOnUpdate) {
dispose(this.disposeOnUpdate);
}
this.disposeOnUpdate = disposable;
this.show();
}, 20));
@ -134,13 +141,7 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
// log in telemetry
if (this.telemetryService) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: e.action.id, from: 'debugActionsWidget' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: e.action.id, from: 'debugActionsWidget' });
}
}));
this._register(dom.addDisposableListener(window, dom.EventType.RESIZE, () => this.setCoordinates()));
@ -263,14 +264,17 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
dom.hide(this.$el);
}
public static getActions(menu: IMenu, debugService: IDebugService, instantiationService: IInstantiationService): IAction[] {
public static getActions(menu: IMenu, debugService: IDebugService, instantiationService: IInstantiationService): { actions: IAction[], disposable: IDisposable } {
const actions: IAction[] = [];
createAndFillInActionBarActions(menu, undefined, actions, () => false);
const disposable = createAndFillInActionBarActions(menu, undefined, actions, () => false);
if (debugService.getViewModel().isMultiSessionView()) {
actions.push(instantiationService.createInstance(FocusSessionAction, FocusSessionAction.ID, FocusSessionAction.LABEL));
}
return actions.filter(a => !(a instanceof Separator)); // do not render separators for now
return {
actions: actions.filter(a => !(a instanceof Separator)), // do not render separators for now
disposable
};
}
public dispose(): void {
@ -280,5 +284,8 @@ export class DebugToolBar extends Themable implements IWorkbenchContribution {
this.$el.remove();
delete this.$el;
}
if (this.disposeOnUpdate) {
dispose(this.disposeOnUpdate);
}
}
}

View file

@ -41,6 +41,7 @@ export class DebugViewlet extends ViewContainerViewlet {
private breakpointView: ViewletPanel;
private panelListeners = new Map<string, IDisposable>();
private debugToolBarMenu: IMenu;
private disposeOnTitleUpdate: IDisposable;
constructor(
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@ -114,7 +115,14 @@ export class DebugViewlet extends ViewContainerViewlet {
this.debugToolBarMenu = this.menuService.createMenu(MenuId.DebugToolBar, this.contextKeyService);
this._register(this.debugToolBarMenu);
}
return DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
const { actions, disposable } = DebugToolBar.getActions(this.debugToolBarMenu, this.debugService, this.instantiationService);
if (this.disposeOnTitleUpdate) {
dispose(this.disposeOnTitleUpdate);
}
this.disposeOnTitleUpdate = disposable;
return actions;
}
get showInitialDebugActions(): boolean {

View file

@ -219,7 +219,6 @@
.extensions-viewlet > .extensions .extension > .details > .footer > .author {
flex: 1;
font-size: 90%;
padding-right: 6px;
opacity: 0.9;
font-weight: 600;
}

View file

@ -17,6 +17,7 @@ import { editorWidgetBackground, editorWidgetForeground, widgetShadow, inputBord
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
import { Button } from 'vs/base/browser/ui/button/button';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
import { IProductService } from 'vs/platform/product/common/product';
@ -212,14 +213,7 @@ export class FeedbackDropdown extends Dropdown {
const actionId = 'workbench.action.openIssueReporter';
this.commandService.executeCommand(actionId);
this.hide();
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionId, from: 'feedback' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: actionId, from: 'feedback' });
}));
// Contact: Request a Feature

View file

@ -200,6 +200,7 @@ const copyRelativePathCommand = {
appendEditorTitleContextMenuItem(COPY_PATH_COMMAND_ID, copyPathCommand.title, ResourceContextKey.IsFileSystemResource, '1_cutcopypaste');
appendEditorTitleContextMenuItem(COPY_RELATIVE_PATH_COMMAND_ID, copyRelativePathCommand.title, ResourceContextKey.IsFileSystemResource, '1_cutcopypaste');
appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, ResourceContextKey.Scheme.isEqualTo(Schemas.file));
appendEditorTitleContextMenuItem(REVEAL_IN_OS_COMMAND_ID, REVEAL_IN_OS_LABEL, ContextKeyExpr.and(IsWebContext.toNegated(), ResourceContextKey.Scheme.isEqualTo(Schemas.userData)));
appendEditorTitleContextMenuItem(REVEAL_IN_EXPLORER_COMMAND_ID, nls.localize('revealInSideBar', "Reveal in Side Bar"), ResourceContextKey.IsFileSystemResource);
function appendEditorTitleContextMenuItem(id: string, title: string, when: ContextKeyExpr, group?: string): void {

View file

@ -1047,12 +1047,12 @@ export const pasteFileHandler = async (accessor: ServicesAccessor) => {
// Cut is done. Make sure to clear cut state.
explorerService.setToCopy([], false);
}
if (stats.length === 1) {
if (stats.length >= 1) {
const stat = stats[0];
if (stat && !stat.isDirectory && stats.length === 1) {
await editorService.openEditor({ resource: stat.resource, options: { pinned: true, preserveFocus: true } });
}
if (stat) {
if (!stat.isDirectory) {
await editorService.openEditor({ resource: stat.resource, options: { pinned: true, preserveFocus: true } });
}
await explorerService.select(stat.resource);
}
}

View file

@ -6,7 +6,7 @@
import * as nls from 'vs/nls';
import { URI } from 'vs/base/common/uri';
import * as perf from 'vs/base/common/performance';
import { Action, IAction } from 'vs/base/common/actions';
import { Action, IAction, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { memoize } from 'vs/base/common/decorators';
import { IFilesConfiguration, ExplorerFolderContext, FilesExplorerFocusedContext, ExplorerFocusedContext, ExplorerRootContext, ExplorerResourceReadonlyContext, IExplorerService, ExplorerResourceCut, ExplorerResourceMoveableToTrash } from 'vs/workbench/contrib/files/common/files';
import { NewFolderAction, NewFileAction, FileCopiedContext, RefreshExplorerView, CollapseExplorerView } from 'vs/workbench/contrib/files/browser/fileActions';
@ -326,13 +326,7 @@ export class ExplorerView extends ViewletPanel {
// Do not react if clicking on directories
return;
}
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'explorer' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'explorer' });
this.editorService.openEditor({ resource: selection[0].resource, options: { preserveFocus: e.editorOptions.preserveFocus, pinned: e.editorOptions.pinned } }, e.sideBySide ? SIDE_GROUP : ACTIVE_GROUP)
.then(undefined, onUnexpectedError);
}

View file

@ -5,7 +5,7 @@
import * as nls from 'vs/nls';
import { RunOnceScheduler } from 'vs/base/common/async';
import { IAction, ActionRunner } from 'vs/base/common/actions';
import { IAction, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@ -345,13 +345,7 @@ export class OpenEditorsView extends ViewletPanel {
private openEditor(element: OpenEditor, options: { preserveFocus: boolean; pinned: boolean; sideBySide: boolean; }): void {
if (element) {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'openEditors' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: 'workbench.files.openFile', from: 'openEditors' });
const preserveActivateGroup = options.sideBySide && options.preserveFocus; // needed for https://github.com/Microsoft/vscode/issues/42399
if (!preserveActivateGroup) {

View file

@ -7,7 +7,7 @@ import * as nls from 'vs/nls';
import * as arrays from 'vs/base/common/arrays';
import * as types from 'vs/base/common/types';
import { Language } from 'vs/base/common/platform';
import { Action } from 'vs/base/common/actions';
import { Action, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Mode, IEntryRunContext, IAutoFocus, IModel, IQuickNavigateConfiguration } from 'vs/base/parts/quickopen/common/quickOpen';
import { QuickOpenEntryGroup, IHighlight, QuickOpenModel, QuickOpenEntry } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
@ -297,13 +297,7 @@ abstract class BaseCommandEntry extends QuickOpenEntryGroup {
setTimeout(async () => {
if (action && (!(action instanceof Action) || action.enabled)) {
try {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: action.id, from: 'quick open' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: action.id, from: 'quick open' });
const promise = action.run();
if (promise) {

View file

@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { getMediaMime } from 'vs/base/common/mime';
const cacheName = 'vscode-resources';
declare const clients: { get(s: string): Promise<any> };
const _pending = new Map<string, Function>();
export function handleMessageEvent(event: MessageEvent): void {
const fn = _pending.get(event.data.token);
if (fn) {
fn(event.data.data);
_pending.delete(event.data.token);
}
}
export async function handleFetchEvent(event: any): Promise<Response | undefined> {
const url = URI.parse(event.request.url);
if (url.path !== '/vscode-resources/fetch') {
return undefined;
}
if (!event.clientId) {
return undefined;
}
const cachedValue = await caches.open(cacheName).then(cache => cache.match(event.request));
if (cachedValue) {
return cachedValue;
}
// console.log('fetch', url.query);
try {
const token = generateUuid();
return new Promise<Response>(async resolve => {
const handle = setTimeout(() => {
resolve(new Response(undefined, { status: 500, statusText: 'timeout' }));
_pending.delete(token);
}, 5000);
_pending.set(token, (data: ArrayBuffer) => {
clearTimeout(handle);
const res = new Response(data, {
status: 200,
headers: { 'Content-Type': getMediaMime(URI.parse(url.query).path) || 'text/plain' }
});
caches.open(cacheName).then(cache => {
cache.put(event.request, res.clone());
resolve(res);
});
});
const client = await clients.get(event.clientId);
client.postMessage({ uri: url.query, token });
});
} catch (err) {
console.error(err);
return new Response(err, { status: 500 });
}
}

View file

@ -4,19 +4,21 @@
*--------------------------------------------------------------------------------------------*/
import { IFileService } from 'vs/platform/files/common/files';
import { DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { getMediaMime } from 'vs/base/common/mime';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchContributionsRegistry, Extensions } from 'vs/workbench/common/contributions';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
export class WebResources {
// todo@joh explore alternative, explicit approach
class ResourcesMutationObserver {
private readonly _regexp = /url\(('|")?(vscode-remote:\/\/.*?)\1\)/g;
private readonly _urlCache = new Map<string, string>();
private readonly _requestCache = new Map<string, Promise<any>>();
private readonly _observer: MutationObserver;
constructor(@IFileService private readonly _fileService: IFileService) {
// todo@joh add observer to more than head-element
// todo@joh explore alternative approach
private readonly _regexp = /url\(('|")?(vscode-remote:\/\/(.*?))\1\)/ig;
constructor() {
this._observer = new MutationObserver(r => this._handleMutation(r));
this._observer.observe(document, {
subtree: true,
@ -24,6 +26,12 @@ export class WebResources {
attributes: true,
attributeFilter: ['style']
});
this.scan();
}
scan(): void {
document.querySelectorAll('style').forEach(value => this._handleStyleNode(value));
// todo@joh more!
}
dispose(): void {
@ -78,39 +86,60 @@ export class WebResources {
}
private async _rewriteUrls(textContent: string): Promise<string> {
const positions: number[] = [];
const promises: Promise<any>[] = [];
let match: RegExpMatchArray | null = null;
while (match = this._regexp.exec(textContent)) {
const remoteUrl = match[2];
positions.push(match.index! + 'url('.length + (typeof match[1] === 'string' ? match[1].length : 0));
positions.push(remoteUrl.length);
if (!this._urlCache.has(remoteUrl)) {
let request = this._requestCache.get(remoteUrl);
if (!request) {
const uri = URI.parse(remoteUrl, true);
request = this._fileService.readFile(uri).then(file => {
const blobUrl = URL.createObjectURL(new Blob([file.value.buffer], { type: getMediaMime(uri.path) }));
this._urlCache.set(remoteUrl, blobUrl);
});
this._requestCache.set(remoteUrl, request);
}
promises.push(request);
}
}
let content = textContent;
await Promise.all(promises);
for (let i = positions.length - 1; i >= 0; i -= 2) {
const start = positions[i - 1];
const len = positions[i];
const url = this._urlCache.get(content.substr(start, len));
content = content.substring(0, start) + url + content.substring(start + len);
}
return content;
return textContent.replace(this._regexp, function (_m, quote, url) {
return `url(${quote}${location.href}vscode-resources/fetch?${encodeURIComponent(url)}${quote})`;
});
}
}
class ResourceServiceWorker {
private readonly _disposables = new DisposableStore();
constructor(
@IFileService private readonly _fileService: IFileService,
) {
this._initServiceWorker();
this._initFetchHandler();
}
dispose(): void {
this._disposables.dispose();
}
private _initServiceWorker(): void {
const url = './resourceServiceWorkerMain.js';
navigator.serviceWorker.register(url).then(() => {
// console.log('registered');
return navigator.serviceWorker.ready;
}).then(() => {
// console.log('ready');
this._disposables.add(new ResourcesMutationObserver());
}).catch(err => {
console.error(err);
});
}
private _initFetchHandler(): void {
const fetchListener: (this: ServiceWorkerContainer, ev: MessageEvent) => void = event => {
const uri = URI.parse(event.data.uri);
this._fileService.readFile(uri).then(file => {
// todo@joh typings
(<any>event.source).postMessage({
token: event.data.token,
data: file.value.buffer.buffer
}, [file.value.buffer.buffer]);
});
};
navigator.serviceWorker.addEventListener('message', fetchListener);
this._disposables.add(toDisposable(() => navigator.serviceWorker.removeEventListener('message', fetchListener)));
}
}
Registry.as<IWorkbenchContributionsRegistry>(Extensions.Workbench).registerWorkbenchContribution(
ResourceServiceWorker,
LifecyclePhase.Starting
);

View file

@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
(function () {
type Handler = {
handleFetchEvent(event: Event): Promise<Response | undefined>;
handleMessageEvent(event: MessageEvent): void;
};
const handlerPromise = new Promise<Handler>((resolve, reject) => {
// load loader
const baseUrl = './out/';
importScripts(baseUrl + 'vs/loader.js');
require.config({
baseUrl,
catchError: true
});
require(['vs/workbench/contrib/resources/browser/resourceServiceWorker'], resolve, reject);
});
self.addEventListener('message', event => {
handlerPromise.then(handler => {
handler.handleMessageEvent(event);
});
});
self.addEventListener('fetch', (event: any) => {
event.respondWith(handlerPromise.then(handler => {
return handler.handleFetchEvent(event).then(value => {
if (value instanceof Response) {
return value;
} else {
return fetch(event.request);
}
});
}));
});
self.addEventListener('install', event => {
//@ts-ignore
event.waitUntil(self.skipWaiting());
});
self.addEventListener('activate', event => {
//@ts-ignore
event.waitUntil(self.clients.claim()); // Become available to all pages
});
})();

View file

@ -786,7 +786,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
};
let identifier: TaskConfig.TaskIdentifier = Objects.assign(Object.create(null), task.defines);
delete identifier['_key'];
Object.keys(identifier).forEach(key => toCustomize![key] = identifier[key]);
Object.keys(identifier).forEach(key => (<any>toCustomize)![key] = identifier[key]);
if (task.configurationProperties.problemMatchers && task.configurationProperties.problemMatchers.length > 0 && Types.isStringArray(task.configurationProperties.problemMatchers)) {
toCustomize.problemMatcher = task.configurationProperties.problemMatchers;
}
@ -796,9 +796,9 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
if (properties) {
for (let property of Object.getOwnPropertyNames(properties)) {
let value = properties[property];
let value = (<any>properties)[property];
if (value !== undefined && value !== null) {
toCustomize[property] = value;
(<any>toCustomize)[property] = value;
}
}
} else {

View file

@ -36,7 +36,8 @@
}();
const workerReady = new Promise(async (resolveWorkerReady) => {
if (!navigator.serviceWorker) {
if (!areServiceWorkersEnabled()) {
console.log('Service Workers are not enabled. Webviews will not work properly');
return resolveWorkerReady();
}
@ -81,9 +82,18 @@
});
});
function areServiceWorkersEnabled() {
try {
return !!navigator.serviceWorker;
} catch (e) {
return false;
}
}
window.createWebviewManager({
postMessage: hostMessaging.postMessage.bind(hostMessaging),
onMessage: hostMessaging.onMessage.bind(hostMessaging),
ready: workerReady,
fakeLoad: true
});
}());

View file

@ -10,7 +10,8 @@
* onMessage: (channel: string, handler: any) => void,
* focusIframeOnCreate?: boolean,
* ready?: Promise<void>,
* onIframeLoaded: (iframe: HTMLIFrameElement) => void
* onIframeLoaded?: (iframe: HTMLIFrameElement) => void,
* fakeLoad: boolean
* }} WebviewHost
*/
@ -157,8 +158,6 @@
initialScrollProgress: undefined
};
// Service worker for resource loading
const FAKE_LOAD = !!navigator.serviceWorker;
/**
* @param {HTMLDocument?} document
@ -363,7 +362,7 @@
newFrame.setAttribute('id', 'pending-frame');
newFrame.setAttribute('frameborder', '0');
newFrame.setAttribute('sandbox', options.allowScripts ? 'allow-scripts allow-forms allow-same-origin' : 'allow-same-origin');
if (FAKE_LOAD) {
if (host.fakeLoad) {
// We should just be able to use srcdoc, but I wasn't
// seeing the service worker applying properly.
// Fake load an empty on the correct origin and then write real html
@ -373,7 +372,7 @@
newFrame.style.cssText = 'display: block; margin: 0; overflow: hidden; position: absolute; width: 100%; height: 100%; visibility: hidden';
document.body.appendChild(newFrame);
if (!FAKE_LOAD) {
if (!host.fakeLoad) {
// write new content onto iframe
newFrame.contentDocument.open();
}
@ -381,7 +380,7 @@
newFrame.contentWindow.addEventListener('keydown', handleInnerKeydown);
newFrame.contentWindow.addEventListener('DOMContentLoaded', e => {
if (FAKE_LOAD) {
if (host.fakeLoad) {
newFrame.contentDocument.open();
newFrame.contentDocument.write(newDocument);
newFrame.contentDocument.close();
@ -446,14 +445,16 @@
// Bubble out link clicks
newFrame.contentWindow.addEventListener('click', handleInnerClick);
host.onIframeLoaded(newFrame);
if (host.onIframeLoaded) {
host.onIframeLoaded(newFrame);
}
}
if (!FAKE_LOAD) {
if (!host.fakeLoad) {
hookupOnLoadHandlers(newFrame);
}
if (!FAKE_LOAD) {
if (!host.fakeLoad) {
newFrame.contentDocument.write(newDocument);
newFrame.contentDocument.close();
}

View file

@ -7,20 +7,20 @@ import { getMediaMime, MIME_UNKNOWN } from 'vs/base/common/mime';
import { extname } from 'vs/base/common/path';
import { URI } from 'vs/base/common/uri';
const webviewMimeTypes = {
'.svg': 'image/svg+xml',
'.txt': 'text/plain',
'.css': 'text/css',
'.js': 'application/javascript',
'.json': 'application/json',
'.html': 'text/html',
'.htm': 'text/html',
'.xhtml': 'application/xhtml+xml',
'.oft': 'font/otf',
'.xml': 'application/xml',
};
const webviewMimeTypes = new Map([
['.svg', 'image/svg+xml'],
['.txt', 'text/plain'],
['.css', 'text/css'],
['.js', 'application/javascript'],
['.json', 'application/json'],
['.html', 'text/html'],
['.htm', 'text/html'],
['.xhtml', 'application/xhtml+xml'],
['.oft', 'font/otf'],
['.xml', 'application/xml'],
]);
export function getWebviewContentMimeType(normalizedPath: URI): string {
const ext = extname(normalizedPath.fsPath).toLowerCase();
return webviewMimeTypes[ext] || getMediaMime(normalizedPath.fsPath) || MIME_UNKNOWN;
return webviewMimeTypes.get(ext) || getMediaMime(normalizedPath.fsPath) || MIME_UNKNOWN;
}

View file

@ -181,7 +181,8 @@ class SvgBlocker extends Disposable {
});
session.onHeadersReceived((details) => {
const contentType: string[] = details.responseHeaders['content-type'] || details.responseHeaders['Content-Type'];
const headers: any = details.responseHeaders;
const contentType: string[] = headers['content-type'] || headers['Content-Type'];
if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) {
const uri = URI.parse(details.url);
if (uri && !this.isAllowedSvg(uri)) {

View file

@ -17,7 +17,7 @@ import { IWindowService, IURIToOpen } from 'vs/platform/windows/common/windows';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { Action, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { Schemas } from 'vs/base/common/network';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
@ -360,13 +360,7 @@ class WelcomePage extends Disposable {
a.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
a.href = 'javascript:void(0)';
a.addEventListener('click', e => {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', {
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', {
id: 'openRecentFolder',
from: telemetryFrom
});

View file

@ -9,7 +9,7 @@ import { Event, Emitter } from 'vs/base/common/event';
import * as errors from 'vs/base/common/errors';
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
import { FileChangeType, FileChangesEvent, IFileService } from 'vs/platform/files/common/files';
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels';
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration';
@ -24,11 +24,51 @@ import { IConfigurationModel } from 'vs/platform/configuration/common/configurat
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { hash } from 'vs/base/common/hash';
export class UserConfiguration extends Disposable {
private readonly parser: ConfigurationModelParser;
private readonly reloadConfigurationScheduler: RunOnceScheduler;
protected readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
constructor(
private readonly userSettingsResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
private readonly fileService: IFileService
) {
super();
this.parser = new ConfigurationModelParser(this.userSettingsResource.toString(), this.scopes);
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
this._register(this.fileService.watch(this.userSettingsResource));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.userSettingsResource))(() => this.reloadConfigurationScheduler.schedule()));
}
async initialize(): Promise<ConfigurationModel> {
return this.reload();
}
async reload(): Promise<ConfigurationModel> {
try {
const content = await this.fileService.readFile(this.userSettingsResource);
this.parser.parseContent(content.value.toString() || '{}');
return this.parser.configurationModel;
} catch (e) {
return new ConfigurationModel();
}
}
reprocess(): ConfigurationModel {
this.parser.parse();
return this.parser.configurationModel;
}
}
export class RemoteUserConfiguration extends Disposable {
private readonly _cachedConfiguration: CachedRemoteUserConfiguration;
private readonly _configurationFileService: ConfigurationFileService;
private _userConfiguration: UserConfiguration | CachedRemoteUserConfiguration;
private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration;
private _userConfigurationInitializationPromise: Promise<ConfigurationModel> | null = null;
private readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
@ -45,7 +85,7 @@ export class RemoteUserConfiguration extends Disposable {
this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache);
remoteAgentService.getEnvironment().then(async environment => {
if (environment) {
const userConfiguration = this._register(new UserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService));
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService));
this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
this._userConfigurationInitializationPromise = userConfiguration.initialize();
const configurationModel = await this._userConfigurationInitializationPromise;
@ -57,7 +97,7 @@ export class RemoteUserConfiguration extends Disposable {
}
async initialize(): Promise<ConfigurationModel> {
if (this._userConfiguration instanceof UserConfiguration) {
if (this._userConfiguration instanceof FileServiceBasedRemoteUserConfiguration) {
return this._userConfiguration.initialize();
}
@ -90,7 +130,7 @@ export class RemoteUserConfiguration extends Disposable {
}
}
export class UserConfiguration extends Disposable {
class FileServiceBasedRemoteUserConfiguration extends Disposable {
private readonly parser: ConfigurationModelParser;
private readonly reloadConfigurationScheduler: RunOnceScheduler;

View file

@ -81,7 +81,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
this.configurationFileService = new ConfigurationFileService(fileService);
this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), this.workspace);
this.cachedFolderConfigs = new ResourceMap<FolderConfiguration>();
this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, this.configurationFileService));
this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, fileService));
this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration)));
if (remoteAuthority) {
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService));

View file

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IAction, IActionRunner, ActionRunner } from 'vs/base/common/actions';
import { IAction, IActionRunner, ActionRunner, WBActionExecutedEvent, WBActionExecutedClassification } from 'vs/base/common/actions';
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
import * as dom from 'vs/base/browser/dom';
import { IContextMenuService, IContextViewService } from 'vs/platform/contextview/browser/contextView';
@ -173,13 +173,7 @@ class NativeContextMenuService extends Disposable implements IContextMenuService
}
private async runAction(actionRunner: IActionRunner, actionToRun: IAction, delegate: IContextMenuDelegate, event: IContextMenuEvent): Promise<void> {
/* __GDPR__
"workbenchActionExecuted" : {
"id" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"from": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' });
this.telemetryService.publicLog2<WBActionExecutedEvent, WBActionExecutedClassification>('workbenchActionExecuted', { id: actionToRun.id, from: 'contextMenu' });
const context = delegate.getActionsContext ? delegate.getActionsContext(event) : event;

View file

@ -388,7 +388,11 @@ export class RemoteFileDialog {
const relativePath = resources.relativePath(currentDisplayUri, directUri);
const isSameRoot = (this.filePickBox.value.length > 1 && currentPath.length > 1) ? equalsIgnoreCase(this.filePickBox.value.substr(0, 2), currentPath.substr(0, 2)) : false;
if (relativePath && isSameRoot) {
const path = resources.joinPath(this.currentFolder, relativePath);
let path = resources.joinPath(this.currentFolder, relativePath);
const directBasename = resources.basename(directUri);
if ((directBasename === '.') || (directBasename === '..')) {
path = this.remoteUriFrom(this.pathAppend(path, directBasename));
}
return resources.hasTrailingPathSeparator(directUri) ? resources.addTrailingPathSeparator(path) : path;
} else {
return directUri;
@ -479,7 +483,7 @@ export class RemoteFileDialog {
} catch (e) {
// do nothing
}
if (statWithoutTrailing && statWithoutTrailing.isDirectory && (resources.basename(valueUri) !== '.')) {
if (statWithoutTrailing && statWithoutTrailing.isDirectory) {
await this.updateItems(inputUriDirname, false, resources.basename(valueUri));
this.badPath = undefined;
return UpdateResult.Updated;
@ -689,7 +693,7 @@ export class RemoteFileDialog {
this.busy = true;
this.userEnteredPathSegment = trailing ? trailing : '';
this.autoCompletePathSegment = '';
const newValue = trailing ? this.pathFromUri(resources.joinPath(newFolder, trailing)) : this.pathFromUri(newFolder, true);
const newValue = trailing ? this.pathAppend(newFolder, trailing) : this.pathFromUri(newFolder, true);
this.currentFolder = resources.addTrailingPathSeparator(newFolder, this.separator);
return this.createItems(this.currentFolder).then(items => {
this.filePickBox.items = items;
@ -728,7 +732,7 @@ export class RemoteFileDialog {
private pathAppend(uri: URI, additional: string): string {
if ((additional === '..') || (additional === '.')) {
const basePath = this.pathFromUri(uri);
return basePath + (this.endsWithSlash(basePath) ? '' : this.separator) + additional;
return basePath + this.separator + additional;
} else {
return this.pathFromUri(resources.joinPath(uri, additional));
}

View file

@ -71,9 +71,9 @@ export class BrowserWorkbenchEnvironmentService implements IEnvironmentService {
this.configuration.remoteAuthority = configuration.remoteAuthority;
if (remoteUserDataUri) {
this.appSettingsHome = remoteUserDataUri || URI.file('/User').with({ scheme: Schemas.userData });
this.settingsResource = joinPath(this.appSettingsHome, 'settings.json');
this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json');
this.appSettingsHome = remoteUserDataUri;
this.settingsResource = joinPath(this.appSettingsHome, 'settings.json').with({ scheme: Schemas.userData });
this.keybindingsResource = joinPath(this.appSettingsHome, 'keybindings.json').with({ scheme: Schemas.userData });
} else {
const appSettingsHome = URI.file('/User').with({ scheme: Schemas.userData });
this.settingsResource = joinPath(appSettingsHome, 'settings.json');

View file

@ -6,6 +6,10 @@
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { memoize } from 'vs/base/common/decorators';
import { URI } from 'vs/base/common/uri';
import { joinPath } from 'vs/base/common/resources';
import { Schemas } from 'vs/base/common/network';
export class WorkbenchEnvironmentService extends EnvironmentService implements IWorkbenchEnvironmentService {
@ -21,4 +25,10 @@ export class WorkbenchEnvironmentService extends EnvironmentService implements I
get configuration(): IWindowConfiguration {
return this._configuration;
}
@memoize
get settingsResource(): URI { return joinPath(this.appSettingsHome, 'settings.json').with({ scheme: Schemas.userData }); }
@memoize
get keybindingsResource(): URI { return joinPath(this.appSettingsHome, 'keybindings.json').with({ scheme: Schemas.userData }); }
}

View file

@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import { mkdir, open, close, read, write, fdatasync } from 'fs';
import * as os from 'os';
import { promisify } from 'util';
import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
import { IFileSystemProvider, FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError } from 'vs/platform/files/common/files';
@ -24,9 +23,14 @@ import { FileWatcher as WindowsWatcherService } from 'vs/workbench/services/file
import { FileWatcher as NsfwWatcherService } from 'vs/workbench/services/files/node/watcher/nsfw/watcherService';
import { FileWatcher as NodeJSWatcherService } from 'vs/workbench/services/files/node/watcher/nodejs/watcherService';
export interface IWatcherOptions {
pollingInterval?: number;
usePolling: boolean;
}
export class DiskFileSystemProvider extends Disposable implements IFileSystemProvider {
constructor(private logService: ILogService) {
constructor(private logService: ILogService, private watcherOptions?: IWatcherOptions) {
super();
}
@ -410,15 +414,15 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
onChange: (changes: IDiskFileChange[]) => void,
onLogMessage: (msg: ILogMessage) => void,
verboseLogging: boolean,
watcherOptions?: { [key: string]: boolean | number | string }
watcherOptions?: IWatcherOptions
): WindowsWatcherService | UnixWatcherService | NsfwWatcherService
};
let watcherOptions = undefined;
if (this.forcePolling()) {
// WSL needs a polling watcher
if (this.watcherOptions && this.watcherOptions.usePolling) {
// requires a polling watcher
watcherImpl = UnixWatcherService;
watcherOptions = { usePolling: true };
watcherOptions = this.watcherOptions;
} else {
// Single Folder Watcher
if (this.recursiveFoldersToWatch.length === 1) {
@ -514,12 +518,6 @@ export class DiskFileSystemProvider extends Disposable implements IFileSystemPro
return createFileSystemProviderError(error, code);
}
forcePolling(): boolean {
// wsl1 needs polling
return isLinux && /^[\.\-0-9]+-Microsoft/.test(os.release());
}
//#endregion
dispose(): void {

View file

@ -8,7 +8,7 @@ import * as extpath from 'vs/base/common/extpath';
import * as path from 'vs/base/common/path';
import * as platform from 'vs/base/common/platform';
import { IDiskFileChange, normalizeFileChanges, ILogMessage } from 'vs/workbench/services/files/node/watcher/watcher';
import * as nsfw from 'vscode-nsfw';
import * as nsfw from 'nsfw';
import { IWatcherService, IWatcherRequest, IWatcherOptions } from 'vs/workbench/services/files/node/watcher/nsfw/watcher';
import { ThrottledDelayer } from 'vs/base/common/async';
import { FileChangeType } from 'vs/platform/files/common/files';
@ -118,7 +118,7 @@ export class NsfwWatcherService implements IWatcherService {
} else if (this._verboseLogging) {
this.log(` >> ignored ${absolutePath}`);
}
absolutePath = path.join(e.directory, e.newFile || '');
absolutePath = path.join(e.newDirectory || e.directory, e.newFile || '');
if (!this._isPathIgnored(absolutePath, this._pathWatchers[request.path].ignored)) {
undeliveredFileEvents.push({ type: FileChangeType.ADDED, path: absolutePath });
} else if (this._verboseLogging) {

View file

@ -103,7 +103,7 @@ export class ChokidarWatcherService implements IWatcherService {
this.log(`Start watching: ${basePath}]`);
}
const pollingInterval = this._pollingInterval || 1000;
const pollingInterval = this._pollingInterval || 5000;
const usePolling = this._usePolling;
if (usePolling && this._verboseLogging) {
this.log(`Use polling instead of fs.watch: Polling interval ${pollingInterval} ms`);

View file

@ -36,11 +36,10 @@ import { MenuRegistry } from 'vs/platform/actions/common/actions';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
// tslint:disable-next-line: import-patterns
import { commandsExtensionPoint } from 'vs/workbench/api/common/menusExtensionPoint';
import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { Disposable } from 'vs/base/common/lifecycle';
import { RunOnceScheduler } from 'vs/base/common/async';
import { URI } from 'vs/base/common/uri';
import { IFileService, FileChangesEvent, FileChangeType } from 'vs/platform/files/common/files';
import { dirname, isEqual } from 'vs/base/common/resources';
import { IFileService } from 'vs/platform/files/common/files';
import { parse } from 'vs/base/common/json';
import * as objects from 'vs/base/common/objects';
import { IKeymapService } from 'vs/workbench/services/keybinding/common/keymapInfo';
@ -560,12 +559,11 @@ class UserKeybindings extends Disposable {
private _keybindings: IUserFriendlyKeybinding[] = [];
get keybindings(): IUserFriendlyKeybinding[] { return this._keybindings; }
private readonly reloadConfigurationScheduler: RunOnceScheduler;
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
private fileWatcherDisposable: IDisposable = Disposable.None;
private directoryWatcherDisposable: IDisposable = Disposable.None;
private readonly reloadConfigurationScheduler: RunOnceScheduler;
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(
private readonly keybindingsResource: URI,
@ -573,40 +571,16 @@ class UserKeybindings extends Disposable {
) {
super();
this._register(fileService.onFileChanges(e => this.handleFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(changed => {
if (changed) {
this._onDidChange.fire();
}
}), 50));
this._register(toDisposable(() => {
this.stopWatchingResource();
this.stopWatchingDirectory();
}));
}
private watchResource(): void {
this.fileWatcherDisposable = this.fileService.watch(this.keybindingsResource);
}
private stopWatchingResource(): void {
this.fileWatcherDisposable.dispose();
this.fileWatcherDisposable = Disposable.None;
}
private watchDirectory(): void {
const directory = dirname(this.keybindingsResource);
this.directoryWatcherDisposable = this.fileService.watch(directory);
}
private stopWatchingDirectory(): void {
this.directoryWatcherDisposable.dispose();
this.directoryWatcherDisposable = Disposable.None;
this._register(this.fileService.watch(this.keybindingsResource));
this._register(Event.filter(this.fileService.onFileChanges, e => e.contains(this.keybindingsResource))(() => this.reloadConfigurationScheduler.schedule()));
}
async initialize(): Promise<void> {
const exists = await this.fileService.exists(this.keybindingsResource);
this.onResourceExists(exists);
await this.reload();
}
@ -621,39 +595,6 @@ class UserKeybindings extends Disposable {
}
return existing ? !objects.equals(existing, this._keybindings) : true;
}
private async handleFileEvents(event: FileChangesEvent): Promise<void> {
const events = event.changes;
let affectedByChanges = false;
// Find changes that affect the resource
for (const event of events) {
affectedByChanges = isEqual(this.keybindingsResource, event.resource);
if (affectedByChanges) {
if (event.type === FileChangeType.ADDED) {
this.onResourceExists(true);
} else if (event.type === FileChangeType.DELETED) {
this.onResourceExists(false);
}
break;
}
}
if (affectedByChanges) {
this.reloadConfigurationScheduler.schedule();
}
}
private onResourceExists(exists: boolean): void {
if (exists) {
this.stopWatchingDirectory();
this.watchResource();
} else {
this.stopWatchingResource();
this.watchDirectory();
}
}
}
let schemaId = 'vscode://schemas/keybindings';

View file

@ -29,6 +29,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { INavigatorWithKeyboard } from 'vs/workbench/services/keybinding/common/navigatorKeyboard';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
export class BrowserKeyboardMapperFactoryBase {
// keyboard mapper
@ -72,6 +73,7 @@ export class BrowserKeyboardMapperFactoryBase {
protected constructor(
private _notificationService: INotificationService,
private _storageService: IStorageService,
private _commandService: ICommandService
) {
this._keyboardMapper = null;
@ -180,6 +182,11 @@ export class BrowserKeyboardMapperFactoryBase {
let score = matchedKeyboardLayout.score;
if (keymap && score < 0) {
const donotAskUpdateKey = 'missing.keyboardlayout.donotask';
if (this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL)) {
return;
}
// the keyboard layout doesn't actually match the key event or the keymap from chromium
this._notificationService.prompt(
Severity.Info,
@ -187,7 +194,11 @@ export class BrowserKeyboardMapperFactoryBase {
[{
label: nls.localize('keyboardLayoutMissing.configure', "Configure"),
run: () => this._commandService.executeCommand('workbench.action.openKeyboardLayoutPicker')
}],
}, {
label: nls.localize('neverAgain', "Don't Show Again"),
isSecondary: true,
run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
}]
);
return;
@ -413,8 +424,8 @@ export class BrowserKeyboardMapperFactoryBase {
}
export class BrowserKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, commandService: ICommandService) {
super(notificationService, commandService);
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService);
const platform = isWindows ? 'win' : isMacintosh ? 'darwin' : 'linux';
@ -549,13 +560,14 @@ class BrowserKeymapService extends Disposable implements IKeymapService {
@IEnvironmentService environmentService: IEnvironmentService,
@IFileService fileService: IFileService,
@INotificationService notificationService: INotificationService,
@IStorageService storageService: IStorageService,
@ICommandService commandService: ICommandService,
@IConfigurationService private configurationService: IConfigurationService,
) {
super();
const keyboardConfig = configurationService.getValue<{ layout: string }>('keyboard');
const layout = keyboardConfig.layout;
this._factory = new BrowserKeyboardMapperFactory(notificationService, commandService);
this._factory = new BrowserKeyboardMapperFactory(notificationService, storageService, commandService);
this.registerKeyboardListener();

View file

@ -11,10 +11,11 @@ import { KeymapInfo, IKeymapInfo } from '../common/keymapInfo';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IStorageService } from 'vs/platform/storage/common/storage';
class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
constructor(notificationService: INotificationService, commandService: ICommandService) {
super(notificationService, commandService);
constructor(notificationService: INotificationService, storageService: IStorageService, commandService: ICommandService) {
super(notificationService, storageService, commandService);
let keymapInfos: IKeymapInfo[] = KeyboardLayoutContribution.INSTANCE.layoutInfos;
this._keymapInfos.push(...keymapInfos.map(info => (new KeymapInfo(info.layout, info.secondaryLayouts, info.mapping, info.isUserKeyboardLayout))));
@ -28,8 +29,9 @@ class TestKeyboardMapperFactory extends BrowserKeyboardMapperFactoryBase {
suite('keyboard layout loader', () => {
let instantiationService: TestInstantiationService = new TestInstantiationService();
let notitifcationService = instantiationService.stub(INotificationService, {});
let storageService = instantiationService.stub(IStorageService, {});
let commandService = instantiationService.stub(ICommandService, {});
let instance = new TestKeyboardMapperFactory(notitifcationService, commandService);
let instance = new TestKeyboardMapperFactory(notitifcationService, storageService, commandService);
test.skip('load default US keyboard layout', () => {
assert.notEqual(instance.activeKeyboardLayout, null);

View file

@ -816,7 +816,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
mimeType: guessMimeTypes(this.resource).join(', '),
ext,
path: hash(path),
reason
reason,
whitelistedjson: undefined as string | undefined
};
if (ext === '.json' && TextFileEditorModel.WHITELIST_JSON.indexOf(fileName) > -1) {

View file

@ -372,18 +372,16 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
}
private updateDynamicCSSRules(themeData: ITheme) {
let cssRules: string[] = [];
let hasRule: { [rule: string]: boolean } = {};
let ruleCollector = {
const cssRules = new Set<string>();
const ruleCollector = {
addRule: (rule: string) => {
if (!hasRule[rule]) {
cssRules.push(rule);
hasRule[rule] = true;
if (!cssRules.has(rule)) {
cssRules.add(rule);
}
}
};
themingRegistry.getThemingParticipants().forEach(p => p(themeData, ruleCollector, this.environmentService));
_applyRules(cssRules.join('\n'), colorThemeRulesClassName);
_applyRules([...cssRules].join('\n'), colorThemeRulesClassName);
}
private applyTheme(newTheme: ColorThemeData, settingsTarget: ConfigurationTarget | undefined | 'auto', silent = false): Promise<IColorTheme | null> {
@ -438,16 +436,21 @@ export class WorkbenchThemeService implements IWorkbenchThemeService {
if (themeData) {
let key = themeType + themeData.extensionId;
if (!this.themeExtensionsActivated.get(key)) {
/* __GDPR__
"activatePlugin" : {
"id" : { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"name": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" },
"isBuiltin": { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
"publisherDisplayName": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"themeId": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('activatePlugin', {
type ActivatePluginClassification = {
id: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
name: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
isBuiltin: { classification: 'SystemMetaData', purpose: 'FeatureInsight', isMeasurement: true };
publisherDisplayName: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
themeId: { classification: 'PublicNonPersonalData', purpose: 'FeatureInsight' };
};
type ActivatePluginEvent = {
id: string;
name: string;
isBuiltin: boolean;
publisherDisplayName: string;
themeId: string;
};
this.telemetryService.publicLog2<ActivatePluginEvent, ActivatePluginClassification>('activatePlugin', {
id: themeData.extensionId,
name: themeData.extensionName,
isBuiltin: themeData.extensionIsBuiltin,

View file

@ -10,6 +10,7 @@ import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources';
import { VSBuffer } from 'vs/base/common/buffer';
import { startsWith } from 'vs/base/common/strings';
export class FileUserDataProvider extends Disposable implements IUserDataProvider {
@ -28,17 +29,17 @@ export class FileUserDataProvider extends Disposable implements IUserDataProvide
}
private handleFileChanges(event: FileChangesEvent): void {
const changedKeys: string[] = [];
const changedPaths: string[] = [];
for (const change of event.changes) {
if (change.resource.scheme === this.userDataHome.scheme) {
const key = this.toKey(change.resource);
if (key) {
changedKeys.push(key);
const path = this.toPath(change.resource);
if (path) {
changedPaths.push(path);
}
}
}
if (changedKeys.length) {
this._onDidChangeFile.fire(changedKeys);
if (changedPaths.length) {
this._onDidChangeFile.fire(changedPaths);
}
}
@ -62,18 +63,20 @@ export class FileUserDataProvider extends Disposable implements IUserDataProvide
async listFiles(path: string): Promise<string[]> {
const result = await this.fileService.resolve(this.toResource(path));
return result.children ? result.children.map(c => this.toKey(c.resource)!) : [];
return result.children ? result.children.map(c => this.toPath(c.resource)!) : [];
}
deleteFile(path: string): Promise<void> {
return this.fileService.del(this.toResource(path));
}
private toResource(key: string): URI {
return resources.joinPath(this.userDataHome, ...key.split('/'));
private toResource(path: string): URI {
return resources.joinPath(this.userDataHome, path);
}
private toKey(resource: URI): string | undefined {
return resources.relativePath(this.userDataHome, resource);
private toPath(resource: URI): string | undefined {
const resourcePath = resource.toString();
const userDataHomePath = this.userDataHome.toString();
return startsWith(resourcePath, userDataHomePath) ? resourcePath.substr(userDataHomePath.length + 1) : undefined;
}
}

View file

@ -8,8 +8,8 @@ import { FileSystemProviderCapabilities, FileWriteOptions, IStat, FileType, File
import { IUserDataProvider } from 'vs/workbench/services/userData/common/userData';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import * as resources from 'vs/base/common/resources';
import { TernarySearchTree } from 'vs/base/common/map';
import { startsWith } from 'vs/base/common/strings';
export class UserDataFileSystemProvider extends Disposable implements IFileSystemProviderWithFileReadWriteCapability {
@ -85,7 +85,9 @@ export class UserDataFileSystemProvider extends Disposable implements IFileSyste
}
private toPath(resource: URI): string | undefined {
return resources.relativePath(this.userDataHome, resource);
const resourcePath = resource.toString();
const userDataHomePath = this.userDataHome.toString();
return startsWith(resourcePath, userDataHomePath) ? resourcePath.substr(userDataHomePath.length + 1) : undefined;
}
}
@ -105,8 +107,8 @@ class UserDataChangesEvent {
return this._pathsTree;
}
contains(keyOrSegment: string): boolean {
return this.pathsTree.findSubstr(keyOrSegment) !== undefined;
contains(pathOrSegment: string): boolean {
return this.pathsTree.findSubstr(pathOrSegment) !== undefined;
}
}

View file

@ -28,6 +28,11 @@ import 'vs/workbench/browser/parts/quickinput/quickInputActions';
//#endregion
//#region --- Remote Resource loading
import 'vs/workbench/contrib/resources/browser/resourceServiceWorkerClient';
//#endregion
//#region --- API Extension Points

View file

@ -3410,9 +3410,9 @@ fs-extra@^2.0.0:
jsonfile "^2.1.0"
fs-extra@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.0.tgz#8cc3f47ce07ef7b3593a11b9fb245f7e34c041d6"
integrity sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==
version "7.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9"
integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^4.0.0"
@ -5909,6 +5909,11 @@ nan@2.8.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.8.0.tgz#ed715f3fe9de02b57a5e6252d90a96675e1f085a"
integrity sha1-7XFfP+neArV6XmJS2QqWZ14fCFo=
nan@^2.0.0, nan@^2.13.2, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nan@^2.10.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.0.tgz#574e360e4d954ab16966ec102c0c049fd961a099"
@ -5919,11 +5924,6 @@ nan@^2.12.1:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552"
integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==
nan@^2.13.2, nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
nan@^2.9.2, nan@~2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
@ -6172,6 +6172,16 @@ npmlog@^4.0.1, npmlog@^4.0.2:
gauge "~2.7.3"
set-blocking "~2.0.0"
nsfw@1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/nsfw/-/nsfw-1.2.5.tgz#febe581af616f7b042f89df133abe62416c4c803"
integrity sha512-m3mwZUKXiCR69PDMLfAmKmiNzy0Oe9LhFE0DYZC5cc1htNj5Hyb1sAgglXhuaDkibFy22AVvPC5cCFB3A6mYIw==
dependencies:
fs-extra "^7.0.0"
lodash.isinteger "^4.0.4"
lodash.isundefined "^3.0.1"
nan "^2.0.0"
nth-check@~1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
@ -9470,16 +9480,6 @@ vscode-nls-dev@3.2.5:
xml2js "^0.4.19"
yargs "^10.1.1"
vscode-nsfw@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vscode-nsfw/-/vscode-nsfw-1.1.2.tgz#9cb9073b5854386801afe41f7152f721b4ea9e80"
integrity sha512-J0So+JNK/5kQboTO1hKNk4ie/wwUegrJilYSY5sVxU9JJlo3aQdP0zi2NtU8CEK3kkN6qRp0MbXCzbT0LKGorg==
dependencies:
fs-extra "^7.0.0"
lodash.isinteger "^4.0.4"
lodash.isundefined "^3.0.1"
nan "^2.10.0"
vscode-proxy-agent@0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/vscode-proxy-agent/-/vscode-proxy-agent-0.4.0.tgz#574833e65405c6333f350f1b9fef9909deccb6b5"