Merge remote-tracking branch 'origin/master' into tyriar/virtual_process
This commit is contained in:
commit
c5853f3aba
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -59,6 +59,5 @@
|
|||
"git.ignoreLimitWarning": true,
|
||||
"remote.extensionKind": {
|
||||
"msjsdiag.debugger-for-chrome": "workspace"
|
||||
},
|
||||
"typescript.experimental.useSeparateSyntaxServer": true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
18
build/npm/update-distro.js
Normal file
18
build/npm/update-distro.js
Normal 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));
|
|
@ -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*(\\()",
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
#define EXTERN_C extern "C"
|
||||
|
||||
class Rectangle {
|
||||
int width, height;
|
||||
public:
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.",
|
||||
|
|
|
@ -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)));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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:;">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
src/vs/editor/contrib/suggest/media/Misc_inverse_16x.svg
Executable file
1
src/vs/editor/contrib/suggest/media/Misc_inverse_16x.svg
Executable 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 |
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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']);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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'];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
45
src/vs/vscode.d.ts
vendored
|
@ -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.
|
||||
*/
|
||||
|
|
38
src/vs/vscode.proposed.d.ts
vendored
38
src/vs/vscode.proposed.d.ts
vendored
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -425,6 +425,8 @@ export type TransferQuickInput = TransferQuickPick | TransferInputBox;
|
|||
|
||||
export interface BaseTransferQuickInput {
|
||||
|
||||
[key: string]: any;
|
||||
|
||||
id: number;
|
||||
|
||||
type?: 'quickPick' | 'inputBox';
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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' });
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -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 |
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
@ -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
|
||||
});
|
||||
})();
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}());
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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 }); }
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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`);
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
36
yarn.lock
36
yarn.lock
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue