mirror of
https://github.com/Microsoft/vscode
synced 2024-10-05 19:02:54 +00:00
Merge branch 'master' into aeschli/cssheadless
This commit is contained in:
commit
90861d4924
181
.eslintrc.json
181
.eslintrc.json
|
@ -63,13 +63,18 @@
|
|||
"browser": [
|
||||
"common"
|
||||
],
|
||||
"electron-main": [
|
||||
"electron-sandbox": [
|
||||
"common",
|
||||
"node"
|
||||
"browser"
|
||||
],
|
||||
"electron-browser": [
|
||||
"common",
|
||||
"browser",
|
||||
"node",
|
||||
"electron-sandbox"
|
||||
],
|
||||
"electron-main": [
|
||||
"common",
|
||||
"node"
|
||||
]
|
||||
}
|
||||
|
@ -104,6 +109,14 @@
|
|||
"**/vs/base/{common,browser}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/base/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/base/node/**",
|
||||
"restrictions": [
|
||||
|
@ -149,13 +162,22 @@
|
|||
"*" // node modules
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/base/parts/*/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/base/parts/*/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/base/parts/*/electron-browser/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -210,14 +232,24 @@
|
|||
"*" // node modules
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/platform/*/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/base/parts/*/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/platform/*/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/platform/*/electron-browser/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,node}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/platform/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -421,18 +453,34 @@
|
|||
"**/vs/**/{common,worker}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/base/parts/*/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/platform/*/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/editor/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/editor/contrib/**", // editor/contrib is equivalent to /browser/ by convention
|
||||
"**/vs/workbench/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/api/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/services/*/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/electron-browser/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/platform/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/editor/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/editor/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/editor/contrib/**", // editor/contrib is equivalent to /browser/ by convention
|
||||
"**/vs/workbench/{common,browser,node,electron-browser,api}/**",
|
||||
"**/vs/workbench/services/*/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/api/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/services/*/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -444,7 +492,7 @@
|
|||
"**/vs/base/**",
|
||||
"**/vs/platform/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"vs/workbench/contrib/files/common/editors/fileEditorInput",
|
||||
"**/vs/workbench/services/**",
|
||||
"**/vs/workbench/test/**",
|
||||
|
@ -508,16 +556,30 @@
|
|||
"*" // node modules
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/services/**/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/**/{common,browser,worker,electron-sandbox}/**",
|
||||
"**/vs/platform/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/api/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/services/**/electron-browser/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/**/{common,browser,worker,node,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/**/{common,browser,worker,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-browser,api}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/api/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -530,7 +592,7 @@
|
|||
"**/vs/base/**",
|
||||
"**/vs/platform/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/services/**",
|
||||
"**/vs/workbench/contrib/**",
|
||||
"**/vs/workbench/test/**",
|
||||
|
@ -624,17 +686,32 @@
|
|||
"*" // node modules
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/contrib/**/electron-sandbox/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/**/{common,browser,worker,electron-sandbox}/**",
|
||||
"**/vs/platform/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/api/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/contrib/**/{common,browser,electron-sandbox}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/vs/workbench/contrib/**/electron-browser/**",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/**/{common,browser,worker,node,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/**/{common,browser,worker,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-browser,api}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/contrib/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/workbench/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/api/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/services/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/contrib/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -654,10 +731,10 @@
|
|||
"restrictions": [
|
||||
"vs/nls",
|
||||
"vs/css!./**/*",
|
||||
"**/vs/base/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/parts/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/code/**/{common,browser,node,electron-browser}/**",
|
||||
"**/vs/base/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/base/parts/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/code/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"*" // node modules
|
||||
]
|
||||
},
|
||||
|
@ -685,6 +762,54 @@
|
|||
"*" // node modules
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/src/vs/workbench/workbench.common.main.ts",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"**/vs/base/**/{common,browser}/**",
|
||||
"**/vs/base/parts/**/{common,browser}/**",
|
||||
"**/vs/platform/**/{common,browser}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/**/{common,browser}/**"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/src/vs/workbench/workbench.web.main.ts",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"**/vs/base/**/{common,browser}/**",
|
||||
"**/vs/base/parts/**/{common,browser}/**",
|
||||
"**/vs/platform/**/{common,browser}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/**/{common,browser}/**",
|
||||
"**/vs/workbench/workbench.common.main"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/src/vs/workbench/workbench.sandbox.main.ts",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"**/vs/base/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/base/parts/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/platform/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/**/{common,browser,electron-sandbox}/**",
|
||||
"**/vs/workbench/workbench.common.main"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/src/vs/workbench/workbench.desktop.main.ts",
|
||||
"restrictions": [
|
||||
"vs/nls",
|
||||
"**/vs/base/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/base/parts/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/platform/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/editor/**",
|
||||
"**/vs/workbench/**/{common,browser,node,electron-sandbox,electron-browser}/**",
|
||||
"**/vs/workbench/workbench.common.main",
|
||||
"**/vs/workbench/workbench.sandbox.main"
|
||||
]
|
||||
},
|
||||
{
|
||||
"target": "**/extensions/**",
|
||||
"restrictions": "**/*"
|
||||
|
|
2
.github/workflows/author-verified.yml
vendored
2
.github/workflows/author-verified.yml
vendored
|
@ -16,7 +16,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
ref: v16
|
||||
ref: v17
|
||||
path: ./actions
|
||||
- name: Install Actions
|
||||
if: github.event_name != 'issues' || contains(github.event.issue.labels.*.name, 'author-verification-requested')
|
||||
|
|
2
.github/workflows/classifier-apply.yml
vendored
2
.github/workflows/classifier-apply.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
ref: v16
|
||||
ref: v17
|
||||
path: ./actions
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
|
|
2
.github/workflows/commands.yml
vendored
2
.github/workflows/commands.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
path: ./actions
|
||||
ref: v16
|
||||
ref: v17
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run Commands
|
||||
|
|
2
.github/workflows/english-please.yml
vendored
2
.github/workflows/english-please.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
ref: v16
|
||||
ref: v17
|
||||
path: ./actions
|
||||
- name: Install Actions
|
||||
if: contains(github.event.issue.labels.*.name, '*english-please')
|
||||
|
|
2
.github/workflows/feature-request.yml
vendored
2
.github/workflows/feature-request.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
|||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
path: ./actions
|
||||
ref: v16
|
||||
ref: v17
|
||||
- name: Install Actions
|
||||
if: github.event_name != 'issues' || contains(github.event.issue.labels.*.name, 'feature-request')
|
||||
run: npm install --production --prefix ./actions
|
||||
|
|
2
.github/workflows/locker.yml
vendored
2
.github/workflows/locker.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
path: ./actions
|
||||
ref: v16
|
||||
ref: v17
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run Locker
|
||||
|
|
2
.github/workflows/needs-more-info-closer.yml
vendored
2
.github/workflows/needs-more-info-closer.yml
vendored
|
@ -13,7 +13,7 @@ jobs:
|
|||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
path: ./actions
|
||||
ref: v16
|
||||
ref: v17
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
- name: Run Needs More Info Closer
|
||||
|
|
2
.github/workflows/on-label.yml
vendored
2
.github/workflows/on-label.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
ref: v16
|
||||
ref: v17
|
||||
path: ./actions
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
|
|
2
.github/workflows/on-open.yml
vendored
2
.github/workflows/on-open.yml
vendored
|
@ -11,7 +11,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
ref: v16
|
||||
ref: v17
|
||||
path: ./actions
|
||||
- name: Install Actions
|
||||
run: npm install --production --prefix ./actions
|
||||
|
|
|
@ -14,7 +14,7 @@ jobs:
|
|||
with:
|
||||
repository: 'microsoft/vscode-github-triage-actions'
|
||||
path: ./actions
|
||||
ref: v16
|
||||
ref: v17
|
||||
- name: Install Actions
|
||||
if: contains(github.event.issue.labels.*.name, 'testplan-item') || contains(github.event.issue.labels.*.name, 'invalid-testplan-item')
|
||||
run: npm install --production --prefix ./actions
|
||||
|
|
2
.yarnrc
2
.yarnrc
|
@ -1,3 +1,3 @@
|
|||
disturl "https://atom.io/download/electron"
|
||||
target "8.3.0"
|
||||
target "7.2.4"
|
||||
runtime "electron"
|
||||
|
|
|
@ -10,11 +10,11 @@ const path = require('path');
|
|||
let window = null;
|
||||
|
||||
app.once('ready', () => {
|
||||
window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, webviewTag: true, enableWebSQL: false } });
|
||||
window = new BrowserWindow({ width: 800, height: 600, webPreferences: { nodeIntegration: true, webviewTag: true } });
|
||||
window.setMenuBarVisibility(false);
|
||||
window.loadURL(url.format({ pathname: path.join(__dirname, 'index.html'), protocol: 'file:', slashes: true }));
|
||||
// window.webContents.openDevTools();
|
||||
window.once('closed', () => window = null);
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => app.quit());
|
||||
app.on('window-all-closed', () => app.quit());
|
|
@ -66,6 +66,7 @@ const vscodeResources = [
|
|||
'out-build/vs/base/node/languagePacks.js',
|
||||
'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,cpuUsage.sh,ps.sh}',
|
||||
'out-build/vs/base/browser/ui/codicons/codicon/**',
|
||||
'out-build/vs/base/parts/sandbox/electron-browser/preload.js',
|
||||
'out-build/vs/workbench/browser/media/*-theme.css',
|
||||
'out-build/vs/workbench/contrib/debug/**/*.json',
|
||||
'out-build/vs/workbench/contrib/externalTerminal/**/*.scpt',
|
||||
|
@ -154,6 +155,7 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
|||
const out = sourceFolderName;
|
||||
|
||||
const checksums = computeChecksums(out, [
|
||||
'vs/base/parts/sandbox/electron-browser/preload.js',
|
||||
'vs/workbench/workbench.desktop.main.js',
|
||||
'vs/workbench/workbench.desktop.main.css',
|
||||
'vs/workbench/services/extensions/node/extensionHostProcess.js',
|
||||
|
|
|
@ -130,6 +130,14 @@ const RULES = [
|
|||
'lib.dom.d.ts' // no DOM
|
||||
]
|
||||
},
|
||||
// Electron (sandbox)
|
||||
{
|
||||
target: '**/vs/**/electron-sandbox/**',
|
||||
allowedTypes: CORE_TYPES,
|
||||
disallowedDefinitions: [
|
||||
'@types/node' // no node.js
|
||||
]
|
||||
},
|
||||
// Electron (renderer): skip
|
||||
{
|
||||
target: '**/vs/**/electron-browser/**',
|
||||
|
|
|
@ -143,6 +143,15 @@ const RULES = [
|
|||
]
|
||||
},
|
||||
|
||||
// Electron (sandbox)
|
||||
{
|
||||
target: '**/vs/**/electron-sandbox/**',
|
||||
allowedTypes: CORE_TYPES,
|
||||
disallowedDefinitions: [
|
||||
'@types/node' // no node.js
|
||||
]
|
||||
},
|
||||
|
||||
// Electron (renderer): skip
|
||||
{
|
||||
target: '**/vs/**/electron-browser/**',
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"git": {
|
||||
"name": "chromium",
|
||||
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
|
||||
"commitHash": "052d3b44972e6d94ef40054d46c150b7cdd7a5d8"
|
||||
"commitHash": "e4745133a1d3745f066e068b8033c6a269b59caf"
|
||||
}
|
||||
},
|
||||
"licenseDetail": [
|
||||
|
@ -40,7 +40,7 @@
|
|||
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
],
|
||||
"isOnlyProductionDependency": true,
|
||||
"version": "80.0.3987.165"
|
||||
"version": "78.0.3904.130"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
@ -48,11 +48,11 @@
|
|||
"git": {
|
||||
"name": "nodejs",
|
||||
"repositoryUrl": "https://github.com/nodejs/node",
|
||||
"commitHash": "42cce5a9d0fd905bf4ad7a2528c36572dfb8b5ad"
|
||||
"commitHash": "787378879acfb212ed4ff824bf9f767a24a5cb43a"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"version": "12.13.0"
|
||||
"version": "12.8.1"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
@ -60,12 +60,12 @@
|
|||
"git": {
|
||||
"name": "electron",
|
||||
"repositoryUrl": "https://github.com/electron/electron",
|
||||
"commitHash": "426d45cd8569fb7731f213159336cea019829ec5"
|
||||
"commitHash": "0552e0d5de46ffa3b481d741f1db5c779e201565"
|
||||
}
|
||||
},
|
||||
"isOnlyProductionDependency": true,
|
||||
"license": "MIT",
|
||||
"version": "8.3.0"
|
||||
"version": "7.2.4"
|
||||
},
|
||||
{
|
||||
"component": {
|
||||
|
|
|
@ -488,7 +488,7 @@
|
|||
"t": "source.batchfile constant.character.escape.batchfile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -510,7 +510,7 @@
|
|||
"t": "source.batchfile constant.character.escape.batchfile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -1555,7 +1555,7 @@
|
|||
"t": "source.coffee string.regexp.multiline.coffee keyword.control.anchor.regexp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.control.anchor.regexp: #DCDCAA",
|
||||
"light_plus": "keyword.control.anchor.regexp: #FF0000",
|
||||
"light_plus": "keyword.control.anchor.regexp: #EE0000",
|
||||
"dark_vs": "keyword.control: #569CD6",
|
||||
"light_vs": "keyword.control: #0000FF",
|
||||
"hc_black": "keyword.control: #C586C0"
|
||||
|
@ -1605,4 +1605,4 @@
|
|||
"hc_black": "string.regexp: #D16969"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
|
@ -191,7 +191,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -257,7 +257,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -389,7 +389,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.block.struct.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -433,7 +433,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.block.struct.cpp meta.body.struct.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -532,7 +532,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.block.struct.cpp meta.body.struct.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -587,7 +587,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -719,7 +719,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -763,7 +763,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -862,7 +862,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -906,7 +906,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1027,7 +1027,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp meta.block.namespace.cpp meta.body.namespace.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1071,7 +1071,7 @@
|
|||
"t": "source.cpp meta.preprocessor.macro.cpp constant.character.escape.line-continuation.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1187,4 +1187,4 @@
|
|||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
|
@ -2314,7 +2314,7 @@
|
|||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp string.quoted.double.cpp constant.character.escape.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -2430,4 +2430,4 @@
|
|||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
|
@ -26,6 +26,7 @@
|
|||
".webmanifest",
|
||||
".js.map",
|
||||
".css.map",
|
||||
".ts.map",
|
||||
".har",
|
||||
".jslintrc",
|
||||
".jsonld"
|
||||
|
|
|
@ -389,7 +389,7 @@
|
|||
"t": "source.json meta.structure.dictionary.json meta.structure.dictionary.value.json meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json constant.character.escape.json",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1165,4 +1165,4 @@
|
|||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
|
@ -136,7 +136,7 @@
|
|||
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -279,7 +279,7 @@
|
|||
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -323,7 +323,7 @@
|
|||
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile comment.line.number-sign.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "comment: #6A9955",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -378,7 +378,7 @@
|
|||
"t": "source.makefile comment.line.number-sign.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "comment: #6A9955",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -554,7 +554,7 @@
|
|||
"t": "source.makefile meta.scope.target.makefile meta.scope.prerequisites.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -884,7 +884,7 @@
|
|||
"t": "source.makefile meta.scope.recipe.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -3029,7 +3029,7 @@
|
|||
"t": "source.makefile constant.character.escape.continuation.makefile",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -1302,7 +1302,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1324,7 +1324,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1346,7 +1346,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1775,7 +1775,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -389,7 +389,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -411,7 +411,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -433,7 +433,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -455,7 +455,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -477,7 +477,7 @@
|
|||
"t": "source.perl string.regexp.find.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -675,7 +675,7 @@
|
|||
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -950,7 +950,7 @@
|
|||
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -1445,7 +1445,7 @@
|
|||
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -2281,7 +2281,7 @@
|
|||
"t": "source.perl string.quoted.double.perl constant.character.escape.perl",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -279,7 +279,7 @@
|
|||
"t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php string.quoted.single.php constant.character.escape.php",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -378,7 +378,7 @@
|
|||
"t": "text.html.php meta.embedded.block.html source.js meta.embedded.block.php source.php string.quoted.single.php constant.character.escape.php",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -565,7 +565,7 @@
|
|||
"t": "source.python string.quoted.single.python constant.character.escape.python",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -2501,7 +2501,7 @@
|
|||
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -2523,7 +2523,7 @@
|
|||
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -2545,7 +2545,7 @@
|
|||
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby constant.character.escape.ruby",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -2578,7 +2578,7 @@
|
|||
"t": "source.ruby string.regexp.classic.ruby meta.group.regexp.ruby meta.group.regexp.ruby constant.character.escape.ruby",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string.regexp: #D16969",
|
||||
"light_vs": "string.regexp: #811F3F",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
|
|
@ -20761,7 +20761,7 @@
|
|||
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-list.scss meta.property-value.scss string.quoted.single.scss constant.character.escape.scss",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -20882,7 +20882,7 @@
|
|||
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-value.scss string.quoted.single.scss constant.character.escape.scss",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -20959,7 +20959,7 @@
|
|||
"t": "source.css.scss meta.at-rule.each.scss meta.at-rule.while.scss meta.property-list.scss meta.property-value.scss string.quoted.double.scss constant.character.escape.scss",
|
||||
"r": {
|
||||
"dark_plus": "constant.character.escape: #D7BA7D",
|
||||
"light_plus": "constant.character.escape: #FF0000",
|
||||
"light_plus": "constant.character.escape: #EE0000",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "constant.character: #569CD6"
|
||||
|
@ -21020,4 +21020,4 @@
|
|||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
|
@ -169,7 +169,7 @@
|
|||
"keyword.control.anchor.regexp"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ff0000"
|
||||
"foreground": "#EE0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -181,7 +181,7 @@
|
|||
{
|
||||
"scope": "constant.character.escape",
|
||||
"settings": {
|
||||
"foreground": "#ff0000"
|
||||
"foreground": "#EE0000"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -42,7 +42,23 @@
|
|||
"pickerGroup.foreground": "#b0b0b0",
|
||||
"terminal.ansiWhite": "#ffffff",
|
||||
"inputOption.activeBorder": "#3655b5",
|
||||
"focusBorder": "#3655b5"
|
||||
"focusBorder": "#3655b5",
|
||||
"terminal.ansiBlack": "#1e1e1e",
|
||||
"terminal.ansiRed": "#C4265E", // the bright color with ~75% transparent on the background
|
||||
"terminal.ansiGreen": "#86B42B",
|
||||
"terminal.ansiYellow": "#B3B42B",
|
||||
"terminal.ansiBlue": "#6A7EC8",
|
||||
"terminal.ansiMagenta": "#8C6BC8",
|
||||
"terminal.ansiCyan": "#56ADBC",
|
||||
"terminal.ansiWhite": "#e3e3dd",
|
||||
"terminal.ansiBrightBlack": "#666666",
|
||||
"terminal.ansiBrightRed": "#f92672",
|
||||
"terminal.ansiBrightGreen": "#A6E22E",
|
||||
"terminal.ansiBrightYellow": "#e2e22e", // hue shifted #A6E22E
|
||||
"terminal.ansiBrightBlue": "#819aff", // hue shifted #AE81FF
|
||||
"terminal.ansiBrightMagenta": "#AE81FF",
|
||||
"terminal.ansiBrightCyan": "#66D9EF",
|
||||
"terminal.ansiBrightWhite": "#f8f8f2"
|
||||
},
|
||||
"tokenColors": [
|
||||
{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"git": {
|
||||
"name": "seti-ui",
|
||||
"repositoryUrl": "https://github.com/jesseweed/seti-ui",
|
||||
"commitHash": "8f22764c37feb7f706465f5186132111a2401b6b"
|
||||
"commitHash": "f3b2775662b0075aab56e5f0c03269f21f3f0f30"
|
||||
}
|
||||
},
|
||||
"version": "0.1.0"
|
||||
|
|
Binary file not shown.
|
@ -1030,12 +1030,6 @@
|
|||
"fontCharacter": "\\E074",
|
||||
"fontColor": "#cc3e44"
|
||||
},
|
||||
"_rmd_light": {
|
||||
"fontColor": "#498ba7"
|
||||
},
|
||||
"_rmd": {
|
||||
"fontColor": "#519aba"
|
||||
},
|
||||
"_rollup_light": {
|
||||
"fontCharacter": "\\E075",
|
||||
"fontColor": "#b8383d"
|
||||
|
@ -1483,7 +1477,7 @@
|
|||
"test.tsx": "_react_2",
|
||||
"re": "_reasonml",
|
||||
"r": "_R",
|
||||
"rmd": "_rmd",
|
||||
"rmd": "_R",
|
||||
"erb": "_html_erb",
|
||||
"erb.html": "_html_erb",
|
||||
"html.erb": "_html_erb",
|
||||
|
@ -1678,7 +1672,7 @@
|
|||
"sql": "_db",
|
||||
"swift": "_swift",
|
||||
"typescript": "_typescript",
|
||||
"typescriptreact": "_react",
|
||||
"typescriptreact": "_typescript",
|
||||
"xml": "_xml",
|
||||
"yaml": "_yml",
|
||||
"argdown": "_argdown",
|
||||
|
@ -1811,7 +1805,7 @@
|
|||
"test.tsx": "_react_2_light",
|
||||
"re": "_reasonml_light",
|
||||
"r": "_R_light",
|
||||
"rmd": "_rmd_light",
|
||||
"rmd": "_R_light",
|
||||
"erb": "_html_erb_light",
|
||||
"erb.html": "_html_erb_light",
|
||||
"html.erb": "_html_erb_light",
|
||||
|
@ -1949,7 +1943,7 @@
|
|||
"sql": "_db_light",
|
||||
"swift": "_swift_light",
|
||||
"typescript": "_typescript_light",
|
||||
"typescriptreact": "_react_light",
|
||||
"typescriptreact": "_typescript_light",
|
||||
"xml": "_xml_light",
|
||||
"yaml": "_yml_light",
|
||||
"argdown": "_argdown_light",
|
||||
|
@ -2030,5 +2024,5 @@
|
|||
"npm-debug.log": "_npm_ignored_light"
|
||||
}
|
||||
},
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/8f22764c37feb7f706465f5186132111a2401b6b"
|
||||
"version": "https://github.com/jesseweed/seti-ui/commit/f3b2775662b0075aab56e5f0c03269f21f3f0f30"
|
||||
}
|
|
@ -110,9 +110,10 @@ export class TypeScriptServerSpawner {
|
|||
|
||||
private getForkOptions(kind: ServerKind, configuration: TypeScriptServiceConfiguration) {
|
||||
const debugPort = TypeScriptServerSpawner.getDebugPort(kind);
|
||||
const inspectFlag = process.env['TSS_DEBUG_BRK'] ? '--inspect-brk' : '--inspect';
|
||||
const tsServerForkOptions: electron.ForkOptions = {
|
||||
execArgv: [
|
||||
...(debugPort ? [`--inspect=${debugPort}`] : []),
|
||||
...(debugPort ? [`${inspectFlag}=${debugPort}`] : []),
|
||||
...(configuration.maxTsServerMemory ? [`--max-old-space-size=${configuration.maxTsServerMemory}`] : [])
|
||||
]
|
||||
};
|
||||
|
@ -200,7 +201,7 @@ export class TypeScriptServerSpawner {
|
|||
// We typically only want to debug the main semantic server
|
||||
return undefined;
|
||||
}
|
||||
const value = process.env['TSS_DEBUG'];
|
||||
const value = process.env['TSS_DEBUG_BRK'] || process.env['TSS_DEBUG'];
|
||||
if (value) {
|
||||
const port = parseInt(value);
|
||||
if (!isNaN(port)) {
|
||||
|
|
|
@ -29,31 +29,34 @@ suite('vscode API - languages', () => {
|
|||
const doc = await vscode.workspace.openTextDocument(file);
|
||||
const langIdNow = doc.languageId;
|
||||
let clock = 0;
|
||||
const disposables: vscode.Disposable[] = [];
|
||||
|
||||
let close = new Promise(resolve => {
|
||||
vscode.workspace.onDidCloseTextDocument(e => {
|
||||
disposables.push(vscode.workspace.onDidCloseTextDocument(e => {
|
||||
if (e === doc) {
|
||||
assert.equal(doc.languageId, langIdNow);
|
||||
assert.equal(clock, 0);
|
||||
clock += 1;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
let open = new Promise(resolve => {
|
||||
vscode.workspace.onDidOpenTextDocument(e => {
|
||||
disposables.push(vscode.workspace.onDidOpenTextDocument(e => {
|
||||
if (e === doc) { // same instance!
|
||||
assert.equal(doc.languageId, 'json');
|
||||
assert.equal(clock, 1);
|
||||
clock += 1;
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}));
|
||||
});
|
||||
let change = vscode.languages.setTextDocumentLanguage(doc, 'json');
|
||||
await Promise.all([change, close, open]);
|
||||
assert.equal(clock, 2);
|
||||
assert.equal(doc.languageId, 'json');
|
||||
disposables.forEach(disposable => disposable.dispose());
|
||||
disposables.length = 0;
|
||||
});
|
||||
|
||||
test('setTextDocumentLanguage -> error when language does not exist', async function () {
|
||||
|
|
|
@ -318,10 +318,14 @@ suite('notebook workflow', () => {
|
|||
// ---- move up and down ---- //
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(vscode.notebook.activeNotebookEditor!.selection!), 1,
|
||||
`first move down, active cell ${vscode.notebook.activeNotebookEditor!.selection!.uri.toString()}, ${vscode.notebook.activeNotebookEditor!.selection!.source}`);
|
||||
|
||||
await vscode.commands.executeCommand('notebook.cell.moveDown');
|
||||
activeCell = vscode.notebook.activeNotebookEditor!.selection;
|
||||
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(activeCell!), 2);
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells.indexOf(activeCell!), 2,
|
||||
`second move down, active cell ${vscode.notebook.activeNotebookEditor!.selection!.uri.toString()}, ${vscode.notebook.activeNotebookEditor!.selection!.source}`);
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[0].source, 'test');
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[1].source, '');
|
||||
assert.equal(vscode.notebook.activeNotebookEditor!.document.cells[2].source, 'test');
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
"css-loader": "^3.2.0",
|
||||
"debounce": "^1.0.0",
|
||||
"deemon": "^1.4.0",
|
||||
"electron": "8.3.0",
|
||||
"electron": "7.2.4",
|
||||
"eslint": "6.8.0",
|
||||
"eslint-plugin-jsdoc": "^19.1.0",
|
||||
"event-stream": "3.3.4",
|
||||
|
|
|
@ -111,7 +111,10 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
|||
}
|
||||
href = _href(href, false);
|
||||
if (options.baseUrl) {
|
||||
href = resolvePath(options.baseUrl, href).toString();
|
||||
const hasScheme = /^\w[\w\d+.-]*:/.test(href);
|
||||
if (!hasScheme) {
|
||||
href = resolvePath(options.baseUrl, href).toString();
|
||||
}
|
||||
}
|
||||
title = removeMarkdownEscapes(title);
|
||||
href = removeMarkdownEscapes(href);
|
||||
|
|
|
@ -41,6 +41,7 @@ export interface IMenuOptions {
|
|||
enableMnemonics?: boolean;
|
||||
anchorAlignment?: AnchorAlignment;
|
||||
expandDirection?: Direction;
|
||||
useEventAsContext?: boolean;
|
||||
}
|
||||
|
||||
export interface IMenuStyles {
|
||||
|
@ -316,7 +317,7 @@ export class Menu extends ActionBar {
|
|||
|
||||
return menuActionViewItem;
|
||||
} else {
|
||||
const menuItemOptions: IMenuItemOptions = { enableMnemonics: options.enableMnemonics };
|
||||
const menuItemOptions: IMenuItemOptions = { enableMnemonics: options.enableMnemonics, useEventAsContext: options.useEventAsContext };
|
||||
if (options.getKeyBinding) {
|
||||
const keybinding = options.getKeyBinding(action);
|
||||
if (keybinding) {
|
||||
|
|
|
@ -945,7 +945,8 @@ export class MenuBar extends Disposable {
|
|||
actionRunner: this.actionRunner,
|
||||
enableMnemonics: this.options.alwaysOnMnemonics || (this.mnemonicsInUse && this.options.enableMnemonics),
|
||||
ariaLabel: withNullAsUndefined(customMenu.buttonElement.getAttribute('aria-label')),
|
||||
expandDirection: this.options.compactMode !== undefined ? this.options.compactMode : Direction.Right
|
||||
expandDirection: this.options.compactMode !== undefined ? this.options.compactMode : Direction.Right,
|
||||
useEventAsContext: true
|
||||
};
|
||||
|
||||
let menuWidget = this._register(new Menu(menuHolder, customMenu.actions, menuOptions));
|
||||
|
|
|
@ -727,7 +727,7 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
|||
mouseSupport: false,
|
||||
accessibilityProvider: {
|
||||
getAriaLabel: (element) => element.text,
|
||||
getWidgetAriaLabel: () => localize('selectBox', "Select Box"),
|
||||
getWidgetAriaLabel: () => localize({ key: 'selectBox', comment: ['Behave like native select dropdown element.'] }, "Select Box"),
|
||||
getRole: () => 'option',
|
||||
getWidgetRole: () => 'listbox'
|
||||
}
|
||||
|
|
|
@ -328,8 +328,8 @@ export namespace Event {
|
|||
}
|
||||
|
||||
export interface NodeEventEmitter {
|
||||
on(event: string | symbol, listener: Function): this;
|
||||
removeListener(event: string | symbol, listener: Function): this;
|
||||
on(event: string | symbol, listener: Function): unknown;
|
||||
removeListener(event: string | symbol, listener: Function): unknown;
|
||||
}
|
||||
|
||||
export function fromNodeEventEmitter<T>(emitter: NodeEventEmitter, eventName: string, map: (...args: any[]) => T = id => id): Event<T> {
|
||||
|
|
|
@ -9,10 +9,9 @@ import { ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_
|
|||
export function registerContextMenuListener(): void {
|
||||
ipcMain.on(CONTEXT_MENU_CHANNEL, (event: IpcMainEvent, contextMenuId: number, items: ISerializableContextMenuItem[], onClickChannel: string, options?: IPopupOptions) => {
|
||||
const menu = createMenu(event, onClickChannel, items);
|
||||
const window = BrowserWindow.fromWebContents(event.sender);
|
||||
|
||||
menu.popup({
|
||||
window: window ? window : undefined,
|
||||
window: BrowserWindow.fromWebContents(event.sender),
|
||||
x: options ? options.x : undefined,
|
||||
y: options ? options.y : undefined,
|
||||
positioningItem: options ? options.positioningItem : undefined,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ipcRenderer, Event } from 'electron';
|
||||
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { IContextMenuItem, ISerializableContextMenuItem, CONTEXT_MENU_CLOSE_CHANNEL, CONTEXT_MENU_CHANNEL, IPopupOptions, IContextMenuEvent } from 'vs/base/parts/contextmenu/common/contextmenu';
|
||||
|
||||
let contextMenuIdPool = 0;
|
||||
|
@ -13,7 +13,7 @@ export function popup(items: IContextMenuItem[], options?: IPopupOptions): void
|
|||
|
||||
const contextMenuId = contextMenuIdPool++;
|
||||
const onClickChannel = `vscode:onContextMenu${contextMenuId}`;
|
||||
const onClickChannelHandler = (_event: Event, itemId: number, context: IContextMenuEvent) => {
|
||||
const onClickChannelHandler = (event: unknown, itemId: number, context: IContextMenuEvent) => {
|
||||
const item = processedItems[itemId];
|
||||
if (item.click) {
|
||||
item.click(context);
|
||||
|
@ -21,7 +21,7 @@ export function popup(items: IContextMenuItem[], options?: IPopupOptions): void
|
|||
};
|
||||
|
||||
ipcRenderer.once(onClickChannel, onClickChannelHandler);
|
||||
ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, (_event: Event, closedContextMenuId: number) => {
|
||||
ipcRenderer.once(CONTEXT_MENU_CLOSE_CHANNEL, (event: unknown, closedContextMenuId: number) => {
|
||||
if (closedContextMenuId !== contextMenuId) {
|
||||
return;
|
||||
}
|
|
@ -8,7 +8,7 @@ import { Event } from 'vs/base/common/event';
|
|||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
|
||||
export interface Sender {
|
||||
send(channel: string, msg: Buffer | null): void;
|
||||
send(channel: string, msg: unknown): void;
|
||||
}
|
||||
|
||||
export class Protocol implements IMessagePassingProtocol {
|
||||
|
@ -17,13 +17,13 @@ export class Protocol implements IMessagePassingProtocol {
|
|||
|
||||
send(message: VSBuffer): void {
|
||||
try {
|
||||
this.sender.send('ipc:message', (<Buffer>message.buffer));
|
||||
this.sender.send('vscode:message', message.buffer);
|
||||
} catch (e) {
|
||||
// systems are going down
|
||||
}
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.sender.send('ipc:disconnect', null);
|
||||
this.sender.send('vscode:disconnect', null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,9 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
|
|||
import * as errors from 'vs/base/common/errors';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { getRandomElement } from 'vs/base/common/arrays';
|
||||
import { isFunction } from 'vs/base/common/types';
|
||||
import { isFunction, isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { isUpperAsciiLetter } from 'vs/base/common/strings';
|
||||
|
||||
/**
|
||||
* An `IChannel` is an abstraction over a collection of commands.
|
||||
|
@ -919,3 +921,142 @@ export class StaticRouter<TContext = string> implements IClientRouter<TContext>
|
|||
return await this.route(hub);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//#region createChannelReceiver / createChannelSender
|
||||
|
||||
/**
|
||||
* Use both `createChannelReceiver` and `createChannelSender`
|
||||
* for automated process <=> process communication over methods
|
||||
* and events. You do not need to spell out each method on both
|
||||
* sides, a proxy will take care of this.
|
||||
*
|
||||
* Rules:
|
||||
* - if marshalling is enabled, only `URI` and `RegExp` is converted
|
||||
* automatically for you
|
||||
* - events must follow the naming convention `onUppercase`
|
||||
* - `CancellationToken` is currently not supported
|
||||
* - if a context is provided, you can use `AddFirstParameterToFunctions`
|
||||
* utility to signal this in the receiving side type
|
||||
*/
|
||||
|
||||
export interface IBaseChannelOptions {
|
||||
|
||||
/**
|
||||
* Disables automatic marshalling of `URI`.
|
||||
* If marshalling is disabled, `UriComponents`
|
||||
* must be used instead.
|
||||
*/
|
||||
disableMarshalling?: boolean;
|
||||
}
|
||||
|
||||
export interface IChannelReceiverOptions extends IBaseChannelOptions { }
|
||||
|
||||
export function createChannelReceiver(service: unknown, options?: IChannelReceiverOptions): IServerChannel {
|
||||
const handler = service as { [key: string]: unknown };
|
||||
const disableMarshalling = options && options.disableMarshalling;
|
||||
|
||||
// Buffer any event that should be supported by
|
||||
// iterating over all property keys and finding them
|
||||
const mapEventNameToEvent = new Map<string, Event<unknown>>();
|
||||
for (const key in handler) {
|
||||
if (propertyIsEvent(key)) {
|
||||
mapEventNameToEvent.set(key, Event.buffer(handler[key] as Event<unknown>, true));
|
||||
}
|
||||
}
|
||||
|
||||
return new class implements IServerChannel {
|
||||
|
||||
listen<T>(_: unknown, event: string): Event<T> {
|
||||
const eventImpl = mapEventNameToEvent.get(event);
|
||||
if (eventImpl) {
|
||||
return eventImpl as Event<T>;
|
||||
}
|
||||
|
||||
throw new Error(`Event not found: ${event}`);
|
||||
}
|
||||
|
||||
call(_: unknown, command: string, args?: any[]): Promise<any> {
|
||||
const target = handler[command];
|
||||
if (typeof target === 'function') {
|
||||
|
||||
// Revive unless marshalling disabled
|
||||
if (!disableMarshalling && Array.isArray(args)) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
args[i] = revive(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return target.apply(handler, args);
|
||||
}
|
||||
|
||||
throw new Error(`Method not found: ${command}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface IChannelSenderOptions extends IBaseChannelOptions {
|
||||
|
||||
/**
|
||||
* If provided, will add the value of `context`
|
||||
* to each method call to the target.
|
||||
*/
|
||||
context?: unknown;
|
||||
|
||||
/**
|
||||
* If provided, will not proxy any of the properties
|
||||
* that are part of the Map but rather return that value.
|
||||
*/
|
||||
properties?: Map<string, unknown>;
|
||||
}
|
||||
|
||||
export function createChannelSender<T>(channel: IChannel, options?: IChannelSenderOptions): T {
|
||||
const disableMarshalling = options && options.disableMarshalling;
|
||||
|
||||
return new Proxy({}, {
|
||||
get(_target: T, propKey: PropertyKey) {
|
||||
if (typeof propKey === 'string') {
|
||||
|
||||
// Check for predefined values
|
||||
if (options?.properties?.has(propKey)) {
|
||||
return options.properties.get(propKey);
|
||||
}
|
||||
|
||||
// Event
|
||||
if (propertyIsEvent(propKey)) {
|
||||
return channel.listen(propKey);
|
||||
}
|
||||
|
||||
// Function
|
||||
return async function (...args: any[]) {
|
||||
|
||||
// Add context if any
|
||||
let methodArgs: any[];
|
||||
if (options && !isUndefinedOrNull(options.context)) {
|
||||
methodArgs = [options.context, ...args];
|
||||
} else {
|
||||
methodArgs = args;
|
||||
}
|
||||
|
||||
const result = await channel.call(propKey, methodArgs);
|
||||
|
||||
// Revive unless marshalling disabled
|
||||
if (!disableMarshalling) {
|
||||
return revive(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Property not found: ${String(propKey)}`);
|
||||
}
|
||||
}) as T;
|
||||
}
|
||||
|
||||
function propertyIsEvent(name: string): boolean {
|
||||
// Assume a property is an event if it has a form of "onSomething"
|
||||
return name[0] === 'o' && name[1] === 'n' && isUpperAsciiLetter(name.charCodeAt(2));
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { IPCServer, ClientConnectionEvent } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron';
|
||||
import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron';
|
||||
import { ipcMain, WebContents } from 'electron';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
|
@ -26,7 +26,7 @@ export class Server extends IPCServer {
|
|||
private static readonly Clients = new Map<number, IDisposable>();
|
||||
|
||||
private static getOnDidClientConnect(): Event<ClientConnectionEvent> {
|
||||
const onHello = Event.fromNodeEventEmitter<WebContents>(ipcMain, 'ipc:hello', ({ sender }) => sender);
|
||||
const onHello = Event.fromNodeEventEmitter<WebContents>(ipcMain, 'vscode:hello', ({ sender }) => sender);
|
||||
|
||||
return Event.map(onHello, webContents => {
|
||||
const id = webContents.id;
|
||||
|
@ -39,8 +39,8 @@ export class Server extends IPCServer {
|
|||
const onDidClientReconnect = new Emitter<void>();
|
||||
Server.Clients.set(id, toDisposable(() => onDidClientReconnect.fire()));
|
||||
|
||||
const onMessage = createScopedOnMessageEvent(id, 'ipc:message') as Event<VSBuffer>;
|
||||
const onDidClientDisconnect = Event.any(Event.signal(createScopedOnMessageEvent(id, 'ipc:disconnect')), onDidClientReconnect.event);
|
||||
const onMessage = createScopedOnMessageEvent(id, 'vscode:message') as Event<VSBuffer>;
|
||||
const onDidClientDisconnect = Event.any(Event.signal(createScopedOnMessageEvent(id, 'vscode:disconnect')), onDidClientReconnect.event);
|
||||
const protocol = new Protocol(webContents, onMessage);
|
||||
|
||||
return { protocol, onDidClientDisconnect };
|
||||
|
|
|
@ -5,18 +5,18 @@
|
|||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IPCClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Protocol } from 'vs/base/parts/ipc/node/ipc.electron';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { Protocol } from 'vs/base/parts/ipc/common/ipc.electron';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
|
||||
export class Client extends IPCClient implements IDisposable {
|
||||
|
||||
private protocol: Protocol;
|
||||
|
||||
private static createProtocol(): Protocol {
|
||||
const onMessage = Event.fromNodeEventEmitter<VSBuffer>(ipcRenderer, 'ipc:message', (_, message: Buffer) => VSBuffer.wrap(message));
|
||||
ipcRenderer.send('ipc:hello');
|
||||
const onMessage = Event.fromNodeEventEmitter<VSBuffer>(ipcRenderer, 'vscode:message', (_, message) => VSBuffer.wrap(message));
|
||||
ipcRenderer.send('vscode:hello');
|
||||
return new Protocol(ipcRenderer, onMessage);
|
||||
}
|
||||
|
||||
|
@ -29,4 +29,4 @@ export class Client extends IPCClient implements IDisposable {
|
|||
dispose(): void {
|
||||
this.protocol.dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IServerChannel, IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { revive } from 'vs/base/common/marshalling';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
import { isUpperAsciiLetter } from 'vs/base/common/strings';
|
||||
|
||||
/**
|
||||
* Use both `createChannelReceiver` and `createChannelSender`
|
||||
* for automated process <=> process communication over methods
|
||||
* and events. You do not need to spell out each method on both
|
||||
* sides, a proxy will take care of this.
|
||||
*
|
||||
* Rules:
|
||||
* - if marshalling is enabled, only `URI` and `RegExp` is converted
|
||||
* automatically for you
|
||||
* - events must follow the naming convention `onUppercase`
|
||||
* - `CancellationToken` is currently not supported
|
||||
* - if a context is provided, you can use `AddFirstParameterToFunctions`
|
||||
* utility to signal this in the receiving side type
|
||||
*/
|
||||
|
||||
export interface IBaseChannelOptions {
|
||||
|
||||
/**
|
||||
* Disables automatic marshalling of `URI`.
|
||||
* If marshalling is disabled, `UriComponents`
|
||||
* must be used instead.
|
||||
*/
|
||||
disableMarshalling?: boolean;
|
||||
}
|
||||
|
||||
export interface IChannelReceiverOptions extends IBaseChannelOptions { }
|
||||
|
||||
export function createChannelReceiver(service: unknown, options?: IChannelReceiverOptions): IServerChannel {
|
||||
const handler = service as { [key: string]: unknown };
|
||||
const disableMarshalling = options && options.disableMarshalling;
|
||||
|
||||
// Buffer any event that should be supported by
|
||||
// iterating over all property keys and finding them
|
||||
const mapEventNameToEvent = new Map<string, Event<unknown>>();
|
||||
for (const key in handler) {
|
||||
if (propertyIsEvent(key)) {
|
||||
mapEventNameToEvent.set(key, Event.buffer(handler[key] as Event<unknown>, true));
|
||||
}
|
||||
}
|
||||
|
||||
return new class implements IServerChannel {
|
||||
|
||||
listen<T>(_: unknown, event: string): Event<T> {
|
||||
const eventImpl = mapEventNameToEvent.get(event);
|
||||
if (eventImpl) {
|
||||
return eventImpl as Event<T>;
|
||||
}
|
||||
|
||||
throw new Error(`Event not found: ${event}`);
|
||||
}
|
||||
|
||||
call(_: unknown, command: string, args?: any[]): Promise<any> {
|
||||
const target = handler[command];
|
||||
if (typeof target === 'function') {
|
||||
|
||||
// Revive unless marshalling disabled
|
||||
if (!disableMarshalling && Array.isArray(args)) {
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
args[i] = revive(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return target.apply(handler, args);
|
||||
}
|
||||
|
||||
throw new Error(`Method not found: ${command}`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export interface IChannelSenderOptions extends IBaseChannelOptions {
|
||||
|
||||
/**
|
||||
* If provided, will add the value of `context`
|
||||
* to each method call to the target.
|
||||
*/
|
||||
context?: unknown;
|
||||
}
|
||||
|
||||
export function createChannelSender<T>(channel: IChannel, options?: IChannelSenderOptions): T {
|
||||
const disableMarshalling = options && options.disableMarshalling;
|
||||
|
||||
return new Proxy({}, {
|
||||
get(_target: T, propKey: PropertyKey) {
|
||||
if (typeof propKey === 'string') {
|
||||
|
||||
// Event
|
||||
if (propertyIsEvent(propKey)) {
|
||||
return channel.listen(propKey);
|
||||
}
|
||||
|
||||
// Function
|
||||
return async function (...args: any[]) {
|
||||
|
||||
// Add context if any
|
||||
let methodArgs: any[];
|
||||
if (options && !isUndefinedOrNull(options.context)) {
|
||||
methodArgs = [options.context, ...args];
|
||||
} else {
|
||||
methodArgs = args;
|
||||
}
|
||||
|
||||
const result = await channel.call(propKey, methodArgs);
|
||||
|
||||
// Revive unless marshalling disabled
|
||||
if (!disableMarshalling) {
|
||||
return revive(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
throw new Error(`Property not found: ${String(propKey)}`);
|
||||
}
|
||||
}) as T;
|
||||
}
|
||||
|
||||
function propertyIsEvent(name: string): boolean {
|
||||
// Assume a property is an event if it has a form of "onSomething"
|
||||
return name[0] === 'o' && name[1] === 'n' && isUpperAsciiLetter(name.charCodeAt(2));
|
||||
}
|
|
@ -4,8 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { IChannel, IServerChannel, IMessagePassingProtocol, IPCServer, ClientConnectionEvent, IPCClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { IChannel, IServerChannel, IMessagePassingProtocol, IPCServer, ClientConnectionEvent, IPCClient, createChannelReceiver, createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
|
@ -103,7 +102,7 @@ interface ITestService {
|
|||
error(message: string): Promise<void>;
|
||||
neverComplete(): Promise<void>;
|
||||
neverCompleteCT(cancellationToken: CancellationToken): Promise<void>;
|
||||
buffersLength(buffers: Buffer[]): Promise<number>;
|
||||
buffersLength(buffers: VSBuffer[]): Promise<number>;
|
||||
marshall(uri: URI): Promise<URI>;
|
||||
context(): Promise<unknown>;
|
||||
|
||||
|
@ -135,8 +134,8 @@ class TestService implements ITestService {
|
|||
return new Promise((_, e) => cancellationToken.onCancellationRequested(() => e(canceled())));
|
||||
}
|
||||
|
||||
buffersLength(buffers: Buffer[]): Promise<number> {
|
||||
return Promise.resolve(buffers.reduce((r, b) => r + b.length, 0));
|
||||
buffersLength(buffers: VSBuffer[]): Promise<number> {
|
||||
return Promise.resolve(buffers.reduce((r, b) => r + b.buffer.length, 0));
|
||||
}
|
||||
|
||||
ping(msg: string): void {
|
||||
|
@ -199,7 +198,7 @@ class TestChannelClient implements ITestService {
|
|||
return this.channel.call('neverCompleteCT', undefined, cancellationToken);
|
||||
}
|
||||
|
||||
buffersLength(buffers: Buffer[]): Promise<number> {
|
||||
buffersLength(buffers: VSBuffer[]): Promise<number> {
|
||||
return this.channel.call('buffersLength', buffers);
|
||||
}
|
||||
|
||||
|
@ -317,7 +316,7 @@ suite('Base IPC', function () {
|
|||
});
|
||||
|
||||
test('buffers in arrays', async function () {
|
||||
const r = await ipcService.buffersLength([Buffer.allocUnsafe(2), Buffer.allocUnsafe(3)]);
|
||||
const r = await ipcService.buffersLength([VSBuffer.alloc(2), VSBuffer.alloc(3)]);
|
||||
return assert.equal(r, 5);
|
||||
});
|
||||
});
|
||||
|
@ -383,7 +382,7 @@ suite('Base IPC', function () {
|
|||
});
|
||||
|
||||
test('buffers in arrays', async function () {
|
||||
const r = await ipcService.buffersLength([Buffer.allocUnsafe(2), Buffer.allocUnsafe(3)]);
|
||||
const r = await ipcService.buffersLength([VSBuffer.alloc(2), VSBuffer.alloc(3)]);
|
||||
return assert.equal(r, 5);
|
||||
});
|
||||
});
|
249
src/vs/base/parts/sandbox/common/electronTypes.ts
Normal file
249
src/vs/base/parts/sandbox/common/electronTypes.ts
Normal file
|
@ -0,0 +1,249 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
// #######################################################################
|
||||
// ### ###
|
||||
// ### electron.d.ts types we need in a common layer for reuse ###
|
||||
// ### (copied from Electron 7.x) ###
|
||||
// ### ###
|
||||
// #######################################################################
|
||||
|
||||
|
||||
export interface MessageBoxOptions {
|
||||
/**
|
||||
* Can be `"none"`, `"info"`, `"error"`, `"question"` or `"warning"`. On Windows,
|
||||
* `"question"` displays the same icon as `"info"`, unless you set an icon using
|
||||
* the `"icon"` option. On macOS, both `"warning"` and `"error"` display the same
|
||||
* warning icon.
|
||||
*/
|
||||
type?: string;
|
||||
/**
|
||||
* Array of texts for buttons. On Windows, an empty array will result in one button
|
||||
* labeled "OK".
|
||||
*/
|
||||
buttons?: string[];
|
||||
/**
|
||||
* Index of the button in the buttons array which will be selected by default when
|
||||
* the message box opens.
|
||||
*/
|
||||
defaultId?: number;
|
||||
/**
|
||||
* Title of the message box, some platforms will not show it.
|
||||
*/
|
||||
title?: string;
|
||||
/**
|
||||
* Content of the message box.
|
||||
*/
|
||||
message: string;
|
||||
/**
|
||||
* Extra information of the message.
|
||||
*/
|
||||
detail?: string;
|
||||
/**
|
||||
* If provided, the message box will include a checkbox with the given label.
|
||||
*/
|
||||
checkboxLabel?: string;
|
||||
/**
|
||||
* Initial checked state of the checkbox. `false` by default.
|
||||
*/
|
||||
checkboxChecked?: boolean;
|
||||
// icon?: NativeImage;
|
||||
/**
|
||||
* The index of the button to be used to cancel the dialog, via the `Esc` key. By
|
||||
* default this is assigned to the first button with "cancel" or "no" as the label.
|
||||
* If no such labeled buttons exist and this option is not set, `0` will be used as
|
||||
* the return value.
|
||||
*/
|
||||
cancelId?: number;
|
||||
/**
|
||||
* On Windows Electron will try to figure out which one of the `buttons` are common
|
||||
* buttons (like "Cancel" or "Yes"), and show the others as command links in the
|
||||
* dialog. This can make the dialog appear in the style of modern Windows apps. If
|
||||
* you don't like this behavior, you can set `noLink` to `true`.
|
||||
*/
|
||||
noLink?: boolean;
|
||||
/**
|
||||
* Normalize the keyboard access keys across platforms. Default is `false`.
|
||||
* Enabling this assumes `&` is used in the button labels for the placement of the
|
||||
* keyboard shortcut access key and labels will be converted so they work correctly
|
||||
* on each platform, `&` characters are removed on macOS, converted to `_` on
|
||||
* Linux, and left untouched on Windows. For example, a button label of `Vie&w`
|
||||
* will be converted to `Vie_w` on Linux and `View` on macOS and can be selected
|
||||
* via `Alt-W` on Windows and Linux.
|
||||
*/
|
||||
normalizeAccessKeys?: boolean;
|
||||
}
|
||||
|
||||
export interface MessageBoxReturnValue {
|
||||
/**
|
||||
* The index of the clicked button.
|
||||
*/
|
||||
response: number;
|
||||
/**
|
||||
* The checked state of the checkbox if `checkboxLabel` was set. Otherwise `false`.
|
||||
*/
|
||||
checkboxChecked: boolean;
|
||||
}
|
||||
|
||||
export interface OpenDevToolsOptions {
|
||||
/**
|
||||
* Opens the devtools with specified dock state, can be `right`, `bottom`,
|
||||
* `undocked`, `detach`. Defaults to last used dock state. In `undocked` mode it's
|
||||
* possible to dock back. In `detach` mode it's not.
|
||||
*/
|
||||
mode: ('right' | 'bottom' | 'undocked' | 'detach');
|
||||
/**
|
||||
* Whether to bring the opened devtools window to the foreground. The default is
|
||||
* `true`.
|
||||
*/
|
||||
activate?: boolean;
|
||||
}
|
||||
|
||||
export interface SaveDialogOptions {
|
||||
title?: string;
|
||||
/**
|
||||
* Absolute directory path, absolute file path, or file name to use by default.
|
||||
*/
|
||||
defaultPath?: string;
|
||||
/**
|
||||
* Custom label for the confirmation button, when left empty the default label will
|
||||
* be used.
|
||||
*/
|
||||
buttonLabel?: string;
|
||||
filters?: FileFilter[];
|
||||
/**
|
||||
* Message to display above text fields.
|
||||
*
|
||||
* @platform darwin
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* Custom label for the text displayed in front of the filename text field.
|
||||
*
|
||||
* @platform darwin
|
||||
*/
|
||||
nameFieldLabel?: string;
|
||||
/**
|
||||
* Show the tags input box, defaults to `true`.
|
||||
*
|
||||
* @platform darwin
|
||||
*/
|
||||
showsTagField?: boolean;
|
||||
/**
|
||||
* Create a security scoped bookmark when packaged for the Mac App Store. If this
|
||||
* option is enabled and the file doesn't already exist a blank file will be
|
||||
* created at the chosen path.
|
||||
*
|
||||
* @platform darwin,mas
|
||||
*/
|
||||
securityScopedBookmarks?: boolean;
|
||||
}
|
||||
|
||||
export interface OpenDialogOptions {
|
||||
title?: string;
|
||||
defaultPath?: string;
|
||||
/**
|
||||
* Custom label for the confirmation button, when left empty the default label will
|
||||
* be used.
|
||||
*/
|
||||
buttonLabel?: string;
|
||||
filters?: FileFilter[];
|
||||
/**
|
||||
* Contains which features the dialog should use. The following values are
|
||||
* supported:
|
||||
*/
|
||||
properties?: Array<'openFile' | 'openDirectory' | 'multiSelections' | 'showHiddenFiles' | 'createDirectory' | 'promptToCreate' | 'noResolveAliases' | 'treatPackageAsDirectory'>;
|
||||
/**
|
||||
* Message to display above input boxes.
|
||||
*
|
||||
* @platform darwin
|
||||
*/
|
||||
message?: string;
|
||||
/**
|
||||
* Create security scoped bookmarks when packaged for the Mac App Store.
|
||||
*
|
||||
* @platform darwin,mas
|
||||
*/
|
||||
securityScopedBookmarks?: boolean;
|
||||
}
|
||||
|
||||
export interface OpenDialogReturnValue {
|
||||
/**
|
||||
* whether or not the dialog was canceled.
|
||||
*/
|
||||
canceled: boolean;
|
||||
/**
|
||||
* An array of file paths chosen by the user. If the dialog is cancelled this will
|
||||
* be an empty array.
|
||||
*/
|
||||
filePaths: string[];
|
||||
/**
|
||||
* An array matching the `filePaths` array of base64 encoded strings which contains
|
||||
* security scoped bookmark data. `securityScopedBookmarks` must be enabled for
|
||||
* this to be populated. (For return values, see table here.)
|
||||
*
|
||||
* @platform darwin,mas
|
||||
*/
|
||||
bookmarks?: string[];
|
||||
}
|
||||
|
||||
export interface SaveDialogReturnValue {
|
||||
/**
|
||||
* whether or not the dialog was canceled.
|
||||
*/
|
||||
canceled: boolean;
|
||||
/**
|
||||
* If the dialog is canceled, this will be `undefined`.
|
||||
*/
|
||||
filePath?: string;
|
||||
/**
|
||||
* Base64 encoded string which contains the security scoped bookmark data for the
|
||||
* saved file. `securityScopedBookmarks` must be enabled for this to be present.
|
||||
* (For return values, see table here.)
|
||||
*
|
||||
* @platform darwin,mas
|
||||
*/
|
||||
bookmark?: string;
|
||||
}
|
||||
|
||||
export interface CrashReporterStartOptions {
|
||||
companyName: string;
|
||||
/**
|
||||
* URL that crash reports will be sent to as POST.
|
||||
*/
|
||||
submitURL: string;
|
||||
/**
|
||||
* Defaults to `app.name`.
|
||||
*/
|
||||
productName?: string;
|
||||
/**
|
||||
* Whether crash reports should be sent to the server. Default is `true`.
|
||||
*/
|
||||
uploadToServer?: boolean;
|
||||
/**
|
||||
* Default is `false`.
|
||||
*/
|
||||
ignoreSystemCrashHandler?: boolean;
|
||||
/**
|
||||
* An object you can define that will be sent along with the report. Only string
|
||||
* properties are sent correctly. Nested objects are not supported. When using
|
||||
* Windows, the property names and values must be fewer than 64 characters.
|
||||
*/
|
||||
extra?: Record<string, string>;
|
||||
/**
|
||||
* Directory to store the crash reports temporarily (only used when the crash
|
||||
* reporter is started via `process.crashReporter.start`).
|
||||
*/
|
||||
crashesDirectory?: string;
|
||||
}
|
||||
|
||||
export interface FileFilter {
|
||||
|
||||
// Docs: http://electronjs.org/docs/api/structures/file-filter
|
||||
|
||||
extensions: string[];
|
||||
name: string;
|
||||
}
|
115
src/vs/base/parts/sandbox/electron-browser/preload.js
Normal file
115
src/vs/base/parts/sandbox/electron-browser/preload.js
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
// @ts-check
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
const { ipcRenderer, webFrame, crashReporter } = require('electron');
|
||||
|
||||
// @ts-ignore
|
||||
window.vscode = {
|
||||
|
||||
/**
|
||||
* A minimal set of methods exposed from ipcRenderer
|
||||
* to support communication to electron-main
|
||||
*
|
||||
* @type {typeof import('../electron-sandbox/globals').ipcRenderer}
|
||||
*/
|
||||
ipcRenderer: {
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {any[]} args
|
||||
*/
|
||||
send(channel, ...args) {
|
||||
validateIPC(channel);
|
||||
|
||||
ipcRenderer.send(channel, ...args);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
*/
|
||||
on(channel, listener) {
|
||||
validateIPC(channel);
|
||||
|
||||
ipcRenderer.on(channel, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
*/
|
||||
once(channel, listener) {
|
||||
validateIPC(channel);
|
||||
|
||||
ipcRenderer.once(channel, listener);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
* @param {(event: import('electron').IpcRendererEvent, ...args: any[]) => void} listener
|
||||
*/
|
||||
removeListener(channel, listener) {
|
||||
validateIPC(channel);
|
||||
|
||||
ipcRenderer.removeListener(channel, listener);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Support for methods of webFrame type.
|
||||
*
|
||||
* @type {typeof import('../electron-sandbox/globals').webFrame}
|
||||
*/
|
||||
webFrame: {
|
||||
|
||||
getZoomFactor() {
|
||||
return webFrame.getZoomFactor();
|
||||
},
|
||||
|
||||
getZoomLevel() {
|
||||
return webFrame.getZoomLevel();
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {number} level
|
||||
*/
|
||||
setZoomLevel(level) {
|
||||
webFrame.setZoomLevel(level);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Support for methods of crashReporter type.
|
||||
*
|
||||
* @type {typeof import('../electron-sandbox/globals').crashReporter}
|
||||
*/
|
||||
crashReporter: {
|
||||
|
||||
/**
|
||||
* @param {Electron.CrashReporterStartOptions} options
|
||||
*/
|
||||
start(options) {
|
||||
crashReporter.start(options);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//#region Utilities
|
||||
|
||||
/**
|
||||
* @param {string} channel
|
||||
*/
|
||||
function validateIPC(channel) {
|
||||
if (!channel || !channel.startsWith('vscode:')) {
|
||||
throw new Error(`Unsupported event IPC channel '${channel}'`);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}());
|
93
src/vs/base/parts/sandbox/electron-sandbox/globals.ts
Normal file
93
src/vs/base/parts/sandbox/electron-sandbox/globals.ts
Normal file
|
@ -0,0 +1,93 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CrashReporterStartOptions } from 'vs/base/parts/sandbox/common/electronTypes';
|
||||
|
||||
export const ipcRenderer = (window as any).vscode.ipcRenderer as {
|
||||
|
||||
/**
|
||||
* Listens to `channel`, when a new message arrives `listener` would be called with
|
||||
* `listener(event, args...)`.
|
||||
*/
|
||||
on(channel: string, listener: (event: unknown, ...args: any[]) => void): void;
|
||||
|
||||
/**
|
||||
* Adds a one time `listener` function for the event. This `listener` is invoked
|
||||
* only the next time a message is sent to `channel`, after which it is removed.
|
||||
*/
|
||||
once(channel: string, listener: (event: unknown, ...args: any[]) => void): void;
|
||||
|
||||
/**
|
||||
* Removes the specified `listener` from the listener array for the specified
|
||||
* `channel`.
|
||||
*/
|
||||
removeListener(channel: string, listener: (event: unknown, ...args: any[]) => void): void;
|
||||
|
||||
/**
|
||||
* Send an asynchronous message to the main process via `channel`, along with
|
||||
* arguments. Arguments will be serialized with the Structured Clone Algorithm,
|
||||
* just like `postMessage`, so prototype chains will not be included. Sending
|
||||
* Functions, Promises, Symbols, WeakMaps, or WeakSets will throw an exception.
|
||||
*
|
||||
* > **NOTE**: Sending non-standard JavaScript types such as DOM objects or special
|
||||
* Electron objects is deprecated, and will begin throwing an exception starting
|
||||
* with Electron 9.
|
||||
*
|
||||
* The main process handles it by listening for `channel` with the `ipcMain`
|
||||
* module.
|
||||
*/
|
||||
send(channel: string, ...args: any[]): void;
|
||||
};
|
||||
|
||||
export const webFrame = (window as any).vscode.webFrame as {
|
||||
|
||||
/**
|
||||
* The current zoom factor.
|
||||
*/
|
||||
getZoomFactor(): number;
|
||||
|
||||
/**
|
||||
* The current zoom level.
|
||||
*/
|
||||
getZoomLevel(): number;
|
||||
|
||||
/**
|
||||
* Changes the zoom level to the specified level. The original size is 0 and each
|
||||
* increment above or below represents zooming 20% larger or smaller to default
|
||||
* limits of 300% and 50% of original size, respectively.
|
||||
*/
|
||||
setZoomLevel(level: number): void;
|
||||
};
|
||||
|
||||
export const crashReporter = (window as any).vscode.crashReporter as {
|
||||
|
||||
/**
|
||||
* You are required to call this method before using any other `crashReporter` APIs
|
||||
* and in each process (main/renderer) from which you want to collect crash
|
||||
* reports. You can pass different options to `crashReporter.start` when calling
|
||||
* from different processes.
|
||||
*
|
||||
* **Note** Child processes created via the `child_process` module will not have
|
||||
* access to the Electron modules. Therefore, to collect crash reports from them,
|
||||
* use `process.crashReporter.start` instead. Pass the same options as above along
|
||||
* with an additional one called `crashesDirectory` that should point to a
|
||||
* directory to store the crash reports temporarily. You can test this out by
|
||||
* calling `process.crash()` to crash the child process.
|
||||
*
|
||||
* **Note:** If you need send additional/updated `extra` parameters after your
|
||||
* first call `start` you can call `addExtraParameter` on macOS or call `start`
|
||||
* again with the new/updated `extra` parameters on Linux and Windows.
|
||||
*
|
||||
* **Note:** On macOS and windows, Electron uses a new `crashpad` client for crash
|
||||
* collection and reporting. If you want to enable crash reporting, initializing
|
||||
* `crashpad` from the main process using `crashReporter.start` is required
|
||||
* regardless of which process you want to collect crashes from. Once initialized
|
||||
* this way, the crashpad handler collects crashes from all processes. You still
|
||||
* have to call `crashReporter.start` from the renderer or child process, otherwise
|
||||
* crashes from them will get reported without `companyName`, `productName` or any
|
||||
* of the `extra` information.
|
||||
*/
|
||||
start(options: CrashReporterStartOptions): void;
|
||||
};
|
|
@ -3,13 +3,13 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import * as assert from 'assert';
|
||||
import { ipcRenderer, crashReporter, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
|
||||
export interface INativeOpenDialogOptions {
|
||||
forceNewWindow?: boolean;
|
||||
|
||||
defaultPath?: string;
|
||||
|
||||
telemetryEventName?: string;
|
||||
telemetryExtraData?: ITelemetryData;
|
||||
}
|
||||
suite('Sandbox', () => {
|
||||
test('globals', () => {
|
||||
assert.ok(ipcRenderer);
|
||||
assert.ok(crashReporter);
|
||||
assert.ok(webFrame);
|
||||
});
|
||||
});
|
|
@ -3,10 +3,12 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { clipboard, ipcRenderer, shell, webFrame } from 'electron';
|
||||
import 'vs/css!./media/issueReporter';
|
||||
import { ElectronService, IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { ipcRenderer, webFrame } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import * as os from 'os';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
import { $, windowOpenNoOpener } from 'vs/base/browser/dom';
|
||||
import { Button } from 'vs/base/browser/ui/button/button';
|
||||
import 'vs/base/browser/ui/codicons/codiconStyles'; // make sure codicon css is loaded
|
||||
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
|
||||
|
@ -15,21 +17,19 @@ import { debounce } from 'vs/base/common/decorators';
|
|||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { getDelayedChannel, createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil';
|
||||
import { IssueReporterData as IssueReporterModelData, IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel';
|
||||
import BaseHtml from 'vs/code/electron-browser/issue/issueReporterPage';
|
||||
import 'vs/css!./media/issueReporter';
|
||||
import { localize } from 'vs/nls';
|
||||
import { isRemoteDiagnosticError, SystemInfo } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
import { EnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import { IMainProcessService, MainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { ISettingsSearchIssueReporterData, IssueReporterData, IssueReporterExtensionData, IssueReporterFeatures, IssueReporterStyles, IssueType } from 'vs/platform/issue/node/issue';
|
||||
import { ISettingsSearchIssueReporterData, IssueReporterData, IssueReporterExtensionData, IssueReporterFeatures, IssueReporterStyles, IssueType } from 'vs/platform/issue/common/issue';
|
||||
import { getLogLevel, ILogService } from 'vs/platform/log/common/log';
|
||||
import { FollowerLogService, LoggerChannelClient } from 'vs/platform/log/common/logIpc';
|
||||
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
|
@ -64,6 +64,7 @@ export function startup(configuration: IssueReporterConfiguration) {
|
|||
|
||||
export class IssueReporter extends Disposable {
|
||||
private environmentService!: INativeEnvironmentService;
|
||||
private electronService!: IElectronService;
|
||||
private telemetryService!: ITelemetryService;
|
||||
private logService!: ILogService;
|
||||
private readonly issueReporterModel: IssueReporterModel;
|
||||
|
@ -324,6 +325,9 @@ export class IssueReporter extends Disposable {
|
|||
const mainProcessService = new MainProcessService(configuration.windowId);
|
||||
serviceCollection.set(IMainProcessService, mainProcessService);
|
||||
|
||||
this.electronService = new ElectronService(configuration.windowId, mainProcessService) as IElectronService;
|
||||
serviceCollection.set(IElectronService, this.electronService);
|
||||
|
||||
this.environmentService = new EnvironmentService(configuration, configuration.execPath);
|
||||
|
||||
const logService = new SpdLogService(`issuereporter${configuration.windowId}`, this.environmentService.logsPath, getLogLevel(this.environmentService));
|
||||
|
@ -462,7 +466,7 @@ export class IssueReporter extends Disposable {
|
|||
|
||||
this.addEventListener('extensionBugsLink', 'click', (e: Event) => {
|
||||
const url = (<HTMLElement>e.target).innerText;
|
||||
shell.openExternal(url);
|
||||
windowOpenNoOpener(url);
|
||||
});
|
||||
|
||||
this.addEventListener('disableExtensions', 'keydown', (e: Event) => {
|
||||
|
@ -941,9 +945,9 @@ export class IssueReporter extends Disposable {
|
|||
|
||||
private async writeToClipboard(baseUrl: string, issueBody: string): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
ipcRenderer.once('vscode:issueReporterClipboardResponse', (_: unknown, shouldWrite: boolean) => {
|
||||
ipcRenderer.once('vscode:issueReporterClipboardResponse', async (event: unknown, shouldWrite: boolean) => {
|
||||
if (shouldWrite) {
|
||||
clipboard.writeText(issueBody);
|
||||
await this.electronService.writeClipboardText(issueBody);
|
||||
resolve(baseUrl + `&body=${encodeURIComponent(localize('pasteData', "We have written the needed data into your clipboard because it was too large to send. Please paste."))}`);
|
||||
} else {
|
||||
reject();
|
||||
|
@ -1194,7 +1198,7 @@ export class IssueReporter extends Disposable {
|
|||
event.stopPropagation();
|
||||
// Exclude right click
|
||||
if (event.which < 3) {
|
||||
shell.openExternal((<HTMLAnchorElement>event.target).href);
|
||||
windowOpenNoOpener((<HTMLAnchorElement>event.target).href);
|
||||
this.telemetryService.publicLog2('issueReporterViewSimilarIssue');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/node/issue';
|
||||
import { IssueType, ISettingSearchResult, IssueReporterExtensionData } from 'vs/platform/issue/common/issue';
|
||||
import { SystemInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
|
||||
export interface IssueReporterData {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { IssueReporterModel } from 'vs/code/electron-browser/issue/issueReporterModel';
|
||||
import { normalizeGitHubUrl } from 'vs/platform/issue/common/issueReporterUtil';
|
||||
import { IssueType } from 'vs/platform/issue/node/issue';
|
||||
import { IssueType } from 'vs/platform/issue/common/issue';
|
||||
|
||||
suite('IssueReporter', () => {
|
||||
|
||||
|
|
|
@ -4,16 +4,17 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/processExplorer';
|
||||
import { webFrame, ipcRenderer, clipboard } from 'electron';
|
||||
import { clipboard } from 'electron';
|
||||
import { webFrame, ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { repeat } from 'vs/base/common/strings';
|
||||
import { totalmem } from 'os';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/node/issue';
|
||||
import { ProcessExplorerStyles, ProcessExplorerData } from 'vs/platform/issue/common/issue';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { IContextMenuItem } from 'vs/base/parts/contextmenu/common/contextmenu';
|
||||
import { popup } from 'vs/base/parts/contextmenu/electron-browser/contextmenu';
|
||||
import { popup } from 'vs/base/parts/contextmenu/electron-sandbox/contextmenu';
|
||||
import { ProcessItem } from 'vs/base/common/processes';
|
||||
import { addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
|
@ -369,7 +370,7 @@ function requestProcessList(totalWaitTime: number): void {
|
|||
|
||||
// Wait at least a second between requests.
|
||||
if (waited > 1000) {
|
||||
ipcRenderer.send('windowsInfoRequest');
|
||||
ipcRenderer.send('vscode:windowsInfoRequest');
|
||||
ipcRenderer.send('vscode:listProcesses');
|
||||
} else {
|
||||
requestProcessList(waited);
|
||||
|
@ -393,18 +394,18 @@ export function startup(data: ProcessExplorerData): void {
|
|||
createCloseListener();
|
||||
|
||||
// Map window process pids to titles, annotate process names with this when rendering to distinguish between them
|
||||
ipcRenderer.on('vscode:windowsInfoResponse', (_event: unknown, windows: any[]) => {
|
||||
ipcRenderer.on('vscode:windowsInfoResponse', (event: unknown, windows: any[]) => {
|
||||
mapPidToWindowTitle = new Map<number, string>();
|
||||
windows.forEach(window => mapPidToWindowTitle.set(window.pid, window.title));
|
||||
});
|
||||
|
||||
ipcRenderer.on('vscode:listProcessesResponse', (_event: Event, processRoots: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]) => {
|
||||
ipcRenderer.on('vscode:listProcessesResponse', (event: unknown, processRoots: [{ name: string, rootProcess: ProcessItem | IRemoteDiagnosticError }]) => {
|
||||
updateProcessInfo(processRoots);
|
||||
requestProcessList(0);
|
||||
});
|
||||
|
||||
lastRequestTime = Date.now();
|
||||
ipcRenderer.send('windowsInfoRequest');
|
||||
ipcRenderer.send('vscode:windowsInfoRequest');
|
||||
ipcRenderer.send('vscode:listProcesses');
|
||||
|
||||
document.onkeydown = (e: KeyboardEvent) => {
|
||||
|
|
|
@ -27,7 +27,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper
|
|||
import { TelemetryAppenderChannel } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { ipcRenderer } from 'vs/base/parts/sandbox/electron-sandbox/globals';
|
||||
import { ILogService, LogLevel, ILoggerService } from 'vs/platform/log/common/log';
|
||||
import { LoggerChannelClient, FollowerLogService } from 'vs/platform/log/common/logIpc';
|
||||
import { LocalizationsService } from 'vs/platform/localizations/node/localizations';
|
||||
|
@ -35,26 +35,25 @@ import { ILocalizationsService } from 'vs/platform/localizations/common/localiza
|
|||
import { combinedDisposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DownloadService } from 'vs/platform/download/common/downloadService';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { IChannel, IServerChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { createChannelSender, createChannelReceiver } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { IChannel, IServerChannel, StaticRouter, createChannelSender, createChannelReceiver } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { NodeCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/nodeCachedDataCleaner';
|
||||
import { LanguagePackCachedDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/languagePackCachedDataCleaner';
|
||||
import { StorageDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/storageDataCleaner';
|
||||
import { LogsDataCleaner } from 'vs/code/electron-browser/sharedProcess/contrib/logsDataCleaner';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { SpdLogService } from 'vs/platform/log/node/spdlogService';
|
||||
import { DiagnosticsService, IDiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsService';
|
||||
import { DiagnosticsChannel } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IUserDataSyncService, IUserDataSyncStoreService, registerConfiguration, IUserDataSyncLogService, IUserDataSyncUtilService, IUserDataSyncEnablementService, IUserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { UserDataSyncChannel, UserDataSyncUtilServiceClient, UserDataAutoSyncChannel, StorageKeysSyncRegistryChannelClient, UserDataSyncMachinesServiceChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { LoggerService } from 'vs/platform/log/node/loggerService';
|
||||
import { UserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSyncLog';
|
||||
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
|
||||
|
@ -66,7 +65,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
|||
import { GlobalExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
|
||||
import { UserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSyncEnablementService';
|
||||
import { IAuthenticationTokenService, AuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
|
||||
import { AuthenticationTokenServiceChannel } from 'vs/platform/authentication/common/authenticationIpc';
|
||||
import { AuthenticationTokenServiceChannel } from 'vs/platform/authentication/electron-browser/authenticationIpc';
|
||||
import { UserDataSyncBackupStoreService } from 'vs/platform/userDataSync/common/userDataSyncBackupStoreService';
|
||||
import { IStorageKeysSyncRegistryService } from 'vs/platform/userDataSync/common/storageKeys';
|
||||
import { ExtensionTipsService } from 'vs/platform/extensionManagement/node/extensionTipsService';
|
||||
|
@ -90,7 +89,11 @@ interface ISharedProcessInitData {
|
|||
const eventPrefix = 'monacoworkbench';
|
||||
|
||||
class MainProcessService implements IMainProcessService {
|
||||
constructor(private server: Server, private mainRouter: StaticRouter) { }
|
||||
|
||||
constructor(
|
||||
private server: Server,
|
||||
private mainRouter: StaticRouter
|
||||
) { }
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
|
@ -110,7 +113,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
|||
|
||||
const onExit = () => disposables.dispose();
|
||||
process.once('exit', onExit);
|
||||
ipcRenderer.once('electron-main->shared-process: exit', onExit);
|
||||
ipcRenderer.once('vscode:electron-main->shared-process=exit', onExit);
|
||||
|
||||
disposables.add(server);
|
||||
|
||||
|
@ -298,17 +301,17 @@ async function handshake(configuration: ISharedProcessConfiguration): Promise<vo
|
|||
|
||||
// receive payload from electron-main to start things
|
||||
const data = await new Promise<ISharedProcessInitData>(c => {
|
||||
ipcRenderer.once('electron-main->shared-process: payload', (_: any, r: ISharedProcessInitData) => c(r));
|
||||
ipcRenderer.once('vscode:electron-main->shared-process=payload', (event: unknown, r: ISharedProcessInitData) => c(r));
|
||||
|
||||
// tell electron-main we are ready to receive payload
|
||||
ipcRenderer.send('shared-process->electron-main: ready-for-payload');
|
||||
ipcRenderer.send('vscode:shared-process->electron-main=ready-for-payload');
|
||||
});
|
||||
|
||||
// await IPC connection and signal this back to electron-main
|
||||
const server = await setupIPC(data.sharedIPCHandle);
|
||||
ipcRenderer.send('shared-process->electron-main: ipc-ready');
|
||||
ipcRenderer.send('vscode:shared-process->electron-main=ipc-ready');
|
||||
|
||||
// await initialization and signal this back to electron-main
|
||||
await main(server, data, configuration);
|
||||
ipcRenderer.send('shared-process->electron-main: init-done');
|
||||
ipcRenderer.send('vscode:shared-process->electron-main=init-done');
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import { IProcessEnvironment, isWindows, isMacintosh } from 'vs/base/common/plat
|
|||
import { WindowsMainService } from 'vs/platform/windows/electron-main/windowsMainService';
|
||||
import { IWindowOpenable } from 'vs/platform/windows/common/windows';
|
||||
import { OpenContext } from 'vs/platform/windows/node/window';
|
||||
import { ActiveWindowManager } from 'vs/code/node/activeWindowTracker';
|
||||
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { getShellEnvironment } from 'vs/code/node/shellEnv';
|
||||
import { IUpdateService } from 'vs/platform/update/common/update';
|
||||
|
@ -32,12 +31,12 @@ import { NullTelemetryService, combinedAppender, LogAppender } from 'vs/platform
|
|||
import { TelemetryAppenderClient } from 'vs/platform/telemetry/node/telemetryIpc';
|
||||
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
|
||||
import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties';
|
||||
import { getDelayedChannel, StaticRouter } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { createChannelReceiver } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { getDelayedChannel, StaticRouter, createChannelReceiver } from 'vs/base/parts/ipc/common/ipc';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { ProxyAuthHandler } from 'vs/code/electron-main/auth';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { ActiveWindowManager } from 'vs/platform/windows/electron-main/windowTracker';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { hasWorkspaceFileExtension, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { WorkspacesService } from 'vs/platform/workspaces/electron-main/workspacesService';
|
||||
|
@ -45,14 +44,12 @@ import { getMachineId } from 'vs/base/node/id';
|
|||
import { Win32UpdateService } from 'vs/platform/update/electron-main/updateService.win32';
|
||||
import { LinuxUpdateService } from 'vs/platform/update/electron-main/updateService.linux';
|
||||
import { DarwinUpdateService } from 'vs/platform/update/electron-main/updateService.darwin';
|
||||
import { IIssueService } from 'vs/platform/issue/node/issue';
|
||||
import { IssueMainService } from 'vs/platform/issue/electron-main/issueMainService';
|
||||
import { IssueMainService, IIssueMainService } from 'vs/platform/issue/electron-main/issueMainService';
|
||||
import { LoggerChannel } from 'vs/platform/log/common/logIpc';
|
||||
import { setUnexpectedErrorHandler, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { ElectronURLListener } from 'vs/platform/url/electron-main/electronUrlListener';
|
||||
import { serve as serveDriver } from 'vs/platform/driver/electron-main/driver';
|
||||
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
|
||||
import { MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
|
||||
import { IMenubarMainService, MenubarMainService } from 'vs/platform/menubar/electron-main/menubarMainService';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { registerContextMenuListener } from 'vs/base/parts/contextmenu/electron-main/contextmenu';
|
||||
import { homedir } from 'os';
|
||||
|
@ -65,7 +62,7 @@ import { GlobalStorageDatabaseChannel } from 'vs/platform/storage/node/storageIp
|
|||
import { BackupMainService } from 'vs/platform/backup/electron-main/backupMainService';
|
||||
import { IBackupMainService } from 'vs/platform/backup/electron-main/backup';
|
||||
import { WorkspacesHistoryMainService, IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
|
||||
import { URLService } from 'vs/platform/url/node/urlService';
|
||||
import { NativeURLService } from 'vs/platform/url/common/urlService';
|
||||
import { WorkspacesMainService, IWorkspacesMainService } from 'vs/platform/workspaces/electron-main/workspacesMainService';
|
||||
import { statSync } from 'fs';
|
||||
import { DiagnosticsService } from 'vs/platform/diagnostics/node/diagnosticsIpc';
|
||||
|
@ -472,10 +469,10 @@ export class CodeApplication extends Disposable {
|
|||
const diagnosticsChannel = getDelayedChannel(sharedProcessReady.then(client => client.getChannel('diagnostics')));
|
||||
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService, [diagnosticsChannel]));
|
||||
|
||||
services.set(IIssueService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv]));
|
||||
services.set(IIssueMainService, new SyncDescriptor(IssueMainService, [machineId, this.userEnv]));
|
||||
services.set(IElectronMainService, new SyncDescriptor(ElectronMainService));
|
||||
services.set(IWorkspacesService, new SyncDescriptor(WorkspacesService));
|
||||
services.set(IMenubarService, new SyncDescriptor(MenubarMainService));
|
||||
services.set(IMenubarMainService, new SyncDescriptor(MenubarMainService));
|
||||
|
||||
const storageMainService = new StorageMainService(this.logService, this.environmentService);
|
||||
services.set(IStorageMainService, storageMainService);
|
||||
|
@ -485,7 +482,7 @@ export class CodeApplication extends Disposable {
|
|||
services.set(IBackupMainService, backupMainService);
|
||||
|
||||
services.set(IWorkspacesHistoryMainService, new SyncDescriptor(WorkspacesHistoryMainService));
|
||||
services.set(IURLService, new SyncDescriptor(URLService));
|
||||
services.set(IURLService, new SyncDescriptor(NativeURLService));
|
||||
services.set(IWorkspacesMainService, new SyncDescriptor(WorkspacesMainService));
|
||||
|
||||
// Telemetry
|
||||
|
@ -556,8 +553,8 @@ export class CodeApplication extends Disposable {
|
|||
const updateChannel = new UpdateChannel(updateService);
|
||||
electronIpcServer.registerChannel('update', updateChannel);
|
||||
|
||||
const issueService = accessor.get(IIssueService);
|
||||
const issueChannel = createChannelReceiver(issueService);
|
||||
const issueMainService = accessor.get(IIssueMainService);
|
||||
const issueChannel = createChannelReceiver(issueMainService);
|
||||
electronIpcServer.registerChannel('issue', issueChannel);
|
||||
|
||||
const electronMainService = accessor.get(IElectronMainService);
|
||||
|
@ -573,8 +570,8 @@ export class CodeApplication extends Disposable {
|
|||
const workspacesChannel = createChannelReceiver(workspacesService);
|
||||
electronIpcServer.registerChannel('workspaces', workspacesChannel);
|
||||
|
||||
const menubarService = accessor.get(IMenubarService);
|
||||
const menubarChannel = createChannelReceiver(menubarService);
|
||||
const menubarMainService = accessor.get(IMenubarMainService);
|
||||
const menubarChannel = createChannelReceiver(menubarMainService);
|
||||
electronIpcServer.registerChannel('menubar', menubarChannel);
|
||||
|
||||
const urlService = accessor.get(IURLService);
|
||||
|
|
|
@ -59,8 +59,7 @@ export class ProxyAuthHandler extends Disposable {
|
|||
title: 'VS Code',
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
webviewTag: true,
|
||||
enableWebSQL: false
|
||||
webviewTag: true
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ import { mkdirp } from 'vs/base/node/pfs';
|
|||
import { validatePaths } from 'vs/code/node/paths';
|
||||
import { LifecycleMainService, ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net';
|
||||
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
|
||||
import { createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { ILaunchMainService } from 'vs/platform/launch/electron-main/launchMainService';
|
||||
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { BrowserWindow, ipcMain, WebContents, Event as ElectronEvent } from 'electron';
|
||||
|
@ -32,7 +33,7 @@ export class SharedProcess implements ISharedProcess {
|
|||
@IThemeMainService private readonly themeMainService: IThemeMainService
|
||||
) {
|
||||
// overall ready promise when shared process signals initialization is done
|
||||
this._whenReady = new Promise<void>(c => ipcMain.once('shared-process->electron-main: init-done', () => c(undefined)));
|
||||
this._whenReady = new Promise<void>(c => ipcMain.once('vscode:shared-process->electron-main=init-done', () => c(undefined)));
|
||||
}
|
||||
|
||||
@memoize
|
||||
|
@ -41,10 +42,10 @@ export class SharedProcess implements ISharedProcess {
|
|||
show: false,
|
||||
backgroundColor: this.themeMainService.getBackgroundColor(),
|
||||
webPreferences: {
|
||||
preload: URI.parse(require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js')).fsPath,
|
||||
images: false,
|
||||
nodeIntegration: true,
|
||||
webgl: false,
|
||||
enableWebSQL: false,
|
||||
disableBlinkFeatures: 'Auxclick' // do NOT change, allows us to identify this window as shared-process in the process explorer
|
||||
}
|
||||
});
|
||||
|
@ -105,18 +106,18 @@ export class SharedProcess implements ISharedProcess {
|
|||
|
||||
return new Promise<void>(c => {
|
||||
// send payload once shared process is ready to receive it
|
||||
disposables.add(Event.once(Event.fromNodeEventEmitter(ipcMain, 'shared-process->electron-main: ready-for-payload', ({ sender }: { sender: WebContents }) => sender))(sender => {
|
||||
sender.send('electron-main->shared-process: payload', {
|
||||
disposables.add(Event.once(Event.fromNodeEventEmitter(ipcMain, 'vscode:shared-process->electron-main=ready-for-payload', ({ sender }: { sender: WebContents }) => sender))(sender => {
|
||||
sender.send('vscode:electron-main->shared-process=payload', {
|
||||
sharedIPCHandle: this.environmentService.sharedIPCHandle,
|
||||
args: this.environmentService.args,
|
||||
logLevel: this.logService.getLevel()
|
||||
});
|
||||
|
||||
// signal exit to shared process when we get disposed
|
||||
disposables.add(toDisposable(() => sender.send('electron-main->shared-process: exit')));
|
||||
disposables.add(toDisposable(() => sender.send('vscode:electron-main->shared-process=exit')));
|
||||
|
||||
// complete IPC-ready promise when shared process signals this to us
|
||||
ipcMain.once('shared-process->electron-main: ipc-ready', () => c(undefined));
|
||||
ipcMain.once('vscode:shared-process->electron-main=ipc-ready', () => c(undefined));
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -163,10 +163,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
show: !isFullscreenOrMaximized,
|
||||
title: product.nameLong,
|
||||
webPreferences: {
|
||||
preload: URI.parse(this.doGetPreloadUrl()).fsPath,
|
||||
nodeIntegration: true,
|
||||
nodeIntegrationInWorker: RUN_TEXTMATE_IN_WORKER,
|
||||
webviewTag: true,
|
||||
enableWebSQL: false
|
||||
webviewTag: true
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -777,6 +777,10 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
return `${require.toUrl('vs/code/electron-browser/workbench/workbench.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
|
||||
}
|
||||
|
||||
private doGetPreloadUrl(): string {
|
||||
return require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js');
|
||||
}
|
||||
|
||||
serializeWindowState(): IWindowState {
|
||||
if (!this._win) {
|
||||
return defaultWindowState();
|
||||
|
|
|
@ -12,6 +12,7 @@ import { IUndoRedoService, IResourceUndoRedoElement, UndoRedoElementType, IWorks
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { TextChange, compressConsecutiveTextChanges } from 'vs/editor/common/model/textChange';
|
||||
import * as buffer from 'vs/base/common/buffer';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
function uriGetComparisonKey(resource: URI): string {
|
||||
return resource.toString();
|
||||
|
@ -138,6 +139,10 @@ class SingleModelEditStackData {
|
|||
}
|
||||
}
|
||||
|
||||
export interface IUndoRedoDelegate {
|
||||
prepareUndoRedo(element: MultiModelEditStackElement): Promise<IDisposable> | IDisposable | void;
|
||||
}
|
||||
|
||||
export class SingleModelEditStackElement implements IResourceUndoRedoElement {
|
||||
|
||||
public model: ITextModel | URI;
|
||||
|
@ -224,6 +229,8 @@ export class MultiModelEditStackElement implements IWorkspaceUndoRedoElement {
|
|||
private readonly _editStackElementsArr: SingleModelEditStackElement[];
|
||||
private readonly _editStackElementsMap: Map<string, SingleModelEditStackElement>;
|
||||
|
||||
private _delegate: IUndoRedoDelegate | null;
|
||||
|
||||
public get resources(): readonly URI[] {
|
||||
return this._editStackElementsArr.map(editStackElement => editStackElement.resource);
|
||||
}
|
||||
|
@ -240,6 +247,27 @@ export class MultiModelEditStackElement implements IWorkspaceUndoRedoElement {
|
|||
const key = uriGetComparisonKey(editStackElement.resource);
|
||||
this._editStackElementsMap.set(key, editStackElement);
|
||||
}
|
||||
this._delegate = null;
|
||||
}
|
||||
|
||||
public setDelegate(delegate: IUndoRedoDelegate): void {
|
||||
this._delegate = delegate;
|
||||
}
|
||||
|
||||
public prepareUndoRedo(): Promise<IDisposable> | IDisposable | void {
|
||||
if (this._delegate) {
|
||||
return this._delegate.prepareUndoRedo(this);
|
||||
}
|
||||
}
|
||||
|
||||
public getMissingModels(): URI[] {
|
||||
const result: URI[] = [];
|
||||
for (const editStackElement of this._editStackElementsArr) {
|
||||
if (URI.isUri(editStackElement.model)) {
|
||||
result.push(editStackElement.model);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public setModel(model: ITextModel | URI): void {
|
||||
|
|
|
@ -113,12 +113,12 @@ interface IRawConfig {
|
|||
|
||||
const DEFAULT_EOL = (platform.isLinux || platform.isMacintosh) ? DefaultEndOfLine.LF : DefaultEndOfLine.CRLF;
|
||||
|
||||
interface EditStackPastFutureElements {
|
||||
export interface EditStackPastFutureElements {
|
||||
past: EditStackElement[];
|
||||
future: EditStackElement[];
|
||||
}
|
||||
|
||||
function isEditStackPastFutureElements(undoElements: IPastFutureElements): undoElements is EditStackPastFutureElements {
|
||||
export function isEditStackPastFutureElements(undoElements: IPastFutureElements): undoElements is EditStackPastFutureElements {
|
||||
return (isEditStackElements(undoElements.past) && isEditStackElements(undoElements.future));
|
||||
}
|
||||
|
||||
|
|
66
src/vs/editor/common/services/modelUndoRedoParticipant.ts
Normal file
66
src/vs/editor/common/services/modelUndoRedoParticipant.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { IUndoRedoService, UndoRedoElementType } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { isEditStackPastFutureElements } from 'vs/editor/common/services/modelServiceImpl';
|
||||
import { IUndoRedoDelegate, MultiModelEditStackElement } from 'vs/editor/common/model/editStack';
|
||||
|
||||
export class ModelUndoRedoParticipant extends Disposable implements IUndoRedoDelegate {
|
||||
constructor(
|
||||
@IModelService private readonly _modelService: IModelService,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
@IUndoRedoService private readonly _undoRedoService: IUndoRedoService,
|
||||
) {
|
||||
super();
|
||||
this._register(this._modelService.onModelRemoved((model) => {
|
||||
// a model will get disposed, so let's check if the undo redo stack is maintained
|
||||
const elements = this._undoRedoService.getElements(model.uri);
|
||||
if (elements.past.length === 0 && elements.future.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (!isEditStackPastFutureElements(elements)) {
|
||||
return;
|
||||
}
|
||||
for (const element of elements.past) {
|
||||
if (element.type === UndoRedoElementType.Workspace) {
|
||||
element.setDelegate(this);
|
||||
}
|
||||
}
|
||||
for (const element of elements.future) {
|
||||
if (element.type === UndoRedoElementType.Workspace) {
|
||||
element.setDelegate(this);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public prepareUndoRedo(element: MultiModelEditStackElement): IDisposable | Promise<IDisposable> {
|
||||
// Load all the needed text models
|
||||
const missingModels = element.getMissingModels();
|
||||
if (missingModels.length === 0) {
|
||||
// All models are available!
|
||||
return Disposable.None;
|
||||
}
|
||||
|
||||
const disposablesPromises = missingModels.map(async (uri) => {
|
||||
try {
|
||||
const reference = await this._textModelService.createModelReference(uri);
|
||||
return <IDisposable>reference;
|
||||
} catch (err) {
|
||||
// This model could not be loaded, maybe it was deleted in the meantime?
|
||||
return Disposable.None;
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(disposablesPromises).then(disposables => {
|
||||
return {
|
||||
dispose: () => dispose(disposables)
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
|
@ -359,7 +359,7 @@ export class CommonFindController extends Disposable implements IEditorContribut
|
|||
&& this._editor.hasModel()
|
||||
&& !this._editor.getModel().isTooLargeForSyncing()
|
||||
) {
|
||||
return this._clipboardService.readFindText();
|
||||
return this._clipboardService.readFindTextSync();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
@ -370,7 +370,7 @@ export class CommonFindController extends Disposable implements IEditorContribut
|
|||
&& this._editor.hasModel()
|
||||
&& !this._editor.getModel().isTooLargeForSyncing()
|
||||
) {
|
||||
this._clipboardService.writeFindText(text);
|
||||
this._clipboardService.writeFindTextSync(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService
|
|||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IdleValue, raceCancellation } from 'vs/base/common/async';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
|
@ -38,6 +37,7 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/tex
|
|||
class RenameSkeleton {
|
||||
|
||||
private readonly _providers: RenameProvider[];
|
||||
private _providerRenameIdx: number = 0;
|
||||
|
||||
constructor(
|
||||
private readonly model: ITextModel,
|
||||
|
@ -51,30 +51,45 @@ class RenameSkeleton {
|
|||
}
|
||||
|
||||
async resolveRenameLocation(token: CancellationToken): Promise<RenameLocation & Rejection | undefined> {
|
||||
const firstProvider = this._providers[0];
|
||||
if (!firstProvider) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let res: RenameLocation & Rejection | undefined;
|
||||
if (firstProvider.resolveRenameLocation) {
|
||||
res = withNullAsUndefined(await firstProvider.resolveRenameLocation(this.model, this.position, token));
|
||||
}
|
||||
const rejects: string[] = [];
|
||||
|
||||
if (!res) {
|
||||
const word = this.model.getWordAtPosition(this.position);
|
||||
if (word) {
|
||||
return {
|
||||
range: new Range(this.position.lineNumber, word.startColumn, this.position.lineNumber, word.endColumn),
|
||||
text: word.word
|
||||
};
|
||||
for (this._providerRenameIdx = 0; this._providerRenameIdx < this._providers.length; this._providerRenameIdx++) {
|
||||
const provider = this._providers[this._providerRenameIdx];
|
||||
if (!provider.resolveRenameLocation) {
|
||||
break;
|
||||
}
|
||||
let res = await provider.resolveRenameLocation(this.model, this.position, token);
|
||||
if (!res) {
|
||||
continue;
|
||||
}
|
||||
if (res.rejectReason) {
|
||||
rejects.push(res.rejectReason);
|
||||
continue;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
return res;
|
||||
const word = this.model.getWordAtPosition(this.position);
|
||||
if (!word) {
|
||||
return {
|
||||
range: Range.fromPositions(this.position),
|
||||
text: '',
|
||||
rejectReason: rejects.length > 0 ? rejects.join('\n') : undefined
|
||||
};
|
||||
}
|
||||
return {
|
||||
range: new Range(this.position.lineNumber, word.startColumn, this.position.lineNumber, word.endColumn),
|
||||
text: word.word,
|
||||
rejectReason: rejects.length > 0 ? rejects.join('\n') : undefined
|
||||
};
|
||||
}
|
||||
|
||||
async provideRenameEdits(newName: string, i: number, rejects: string[], token: CancellationToken): Promise<WorkspaceEdit & Rejection> {
|
||||
async provideRenameEdits(newName: string, token: CancellationToken): Promise<WorkspaceEdit & Rejection> {
|
||||
return this._provideRenameEdits(newName, this._providerRenameIdx, [], token);
|
||||
}
|
||||
|
||||
private async _provideRenameEdits(newName: string, i: number, rejects: string[], token: CancellationToken): Promise<WorkspaceEdit & Rejection> {
|
||||
const provider = this._providers[i];
|
||||
if (!provider) {
|
||||
return {
|
||||
|
@ -85,16 +100,21 @@ class RenameSkeleton {
|
|||
|
||||
const result = await provider.provideRenameEdits(this.model, this.position, newName, token);
|
||||
if (!result) {
|
||||
return this.provideRenameEdits(newName, i + 1, rejects.concat(nls.localize('no result', "No result.")), token);
|
||||
return this._provideRenameEdits(newName, i + 1, rejects.concat(nls.localize('no result', "No result.")), token);
|
||||
} else if (result.rejectReason) {
|
||||
return this.provideRenameEdits(newName, i + 1, rejects.concat(result.rejectReason), token);
|
||||
return this._provideRenameEdits(newName, i + 1, rejects.concat(result.rejectReason), token);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export async function rename(model: ITextModel, position: Position, newName: string): Promise<WorkspaceEdit & Rejection> {
|
||||
return new RenameSkeleton(model, position).provideRenameEdits(newName, 0, [], CancellationToken.None);
|
||||
const skeleton = new RenameSkeleton(model, position);
|
||||
const loc = await skeleton.resolveRenameLocation(CancellationToken.None);
|
||||
if (loc?.rejectReason) {
|
||||
return { edits: [], rejectReason: loc.rejectReason };
|
||||
}
|
||||
return skeleton.provideRenameEdits(newName, CancellationToken.None);
|
||||
}
|
||||
|
||||
// --- register actions and commands
|
||||
|
@ -194,7 +214,7 @@ class RenameController implements IEditorContribution {
|
|||
|
||||
this.editor.focus();
|
||||
|
||||
const renameOperation = raceCancellation(skeleton.provideRenameEdits(inputFieldResult.newName, 0, [], this._cts.token), this._cts.token).then(async renameResult => {
|
||||
const renameOperation = raceCancellation(skeleton.provideRenameEdits(inputFieldResult.newName, this._cts.token), this._cts.token).then(async renameResult => {
|
||||
|
||||
if (!renameResult || !this.editor.hasModel()) {
|
||||
return;
|
||||
|
|
|
@ -82,7 +82,7 @@ export class RenameInputField implements IContentWidget {
|
|||
const updateLabel = () => {
|
||||
const [accept, preview] = this._acceptKeybindings;
|
||||
this._keybindingService.lookupKeybinding(accept);
|
||||
this._label!.innerText = localize('label', "{0} to Rename, {1} to Preview", this._keybindingService.lookupKeybinding(accept)?.getLabel(), this._keybindingService.lookupKeybinding(preview)?.getLabel());
|
||||
this._label!.innerText = localize({ key: 'label', comment: ['placeholders are keybindings, e.g "F2 to Rename, Shift+F2 to Preview"'] }, "{0} to Rename, {1} to Preview", this._keybindingService.lookupKeybinding(accept)?.getLabel(), this._keybindingService.lookupKeybinding(preview)?.getLabel());
|
||||
};
|
||||
updateLabel();
|
||||
this._disposables.add(this._keybindingService.onDidUpdateKeybindings(updateLabel));
|
||||
|
|
|
@ -108,12 +108,11 @@ function withTypedEditor<T>(widget: IEditor, codeEditorCallback: (editor: ICodeE
|
|||
export class SimpleEditorModelResolverService implements ITextModelService {
|
||||
public _serviceBrand: undefined;
|
||||
|
||||
private readonly modelService: IModelService | undefined;
|
||||
private editor?: IEditor;
|
||||
|
||||
constructor(modelService: IModelService | undefined) {
|
||||
this.modelService = modelService;
|
||||
}
|
||||
constructor(
|
||||
@IModelService private readonly modelService: IModelService
|
||||
) { }
|
||||
|
||||
public setEditor(editor: IEditor): void {
|
||||
this.editor = editor;
|
||||
|
@ -146,7 +145,7 @@ export class SimpleEditorModelResolverService implements ITextModelService {
|
|||
}
|
||||
|
||||
private findModel(editor: ICodeEditor, resource: URI): ITextModel | null {
|
||||
let model = this.modelService ? this.modelService.getModel(resource) : editor.getModel();
|
||||
let model = this.modelService.getModel(resource);
|
||||
if (model && model.uri.toString() !== resource.toString()) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ import { IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
|||
import { Event } from 'vs/base/common/event';
|
||||
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
|
||||
|
||||
|
||||
export class AuthenticationTokenServiceChannel implements IServerChannel {
|
||||
constructor(private readonly service: IAuthenticationTokenService) { }
|
||||
|
|
@ -11,11 +11,15 @@ export class BrowserClipboardService implements IClipboardService {
|
|||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private _internalResourcesClipboard: URI[] | undefined;
|
||||
private readonly mapTextToType = new Map<string, string>(); // unsupported in web (only in-memory)
|
||||
|
||||
async writeText(text: string, type?: string): Promise<void> {
|
||||
|
||||
// With type: only in-memory is supported
|
||||
if (type) {
|
||||
return; // TODO@sbatten support for writing a specific type into clipboard is unsupported
|
||||
this.mapTextToType.set(type, text);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Guard access to navigator.clipboard with try/catch
|
||||
|
@ -52,8 +56,10 @@ export class BrowserClipboardService implements IClipboardService {
|
|||
}
|
||||
|
||||
async readText(type?: string): Promise<string> {
|
||||
|
||||
// With type: only in-memory is supported
|
||||
if (type) {
|
||||
return ''; // TODO@sbatten support for reading a specific type from clipboard is unsupported
|
||||
return this.mapTextToType.get(type) || '';
|
||||
}
|
||||
|
||||
// Guard access to navigator.clipboard with try/catch
|
||||
|
@ -68,26 +74,42 @@ export class BrowserClipboardService implements IClipboardService {
|
|||
}
|
||||
}
|
||||
|
||||
private findText = ''; // unsupported in web (only in-memory)
|
||||
|
||||
async readFindText(): Promise<string> {
|
||||
return this.findText;
|
||||
}
|
||||
|
||||
async writeFindText(text: string): Promise<void> {
|
||||
this.findText = text;
|
||||
}
|
||||
|
||||
private resources: URI[] = []; // unsupported in web (only in-memory)
|
||||
|
||||
async writeResources(resources: URI[]): Promise<void> {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
async readResources(): Promise<URI[]> {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
async hasResources(): Promise<boolean> {
|
||||
return this.resources.length > 0;
|
||||
}
|
||||
|
||||
/** @deprecated */
|
||||
readTextSync(): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
readFindText(): string {
|
||||
// @ts-expect-error
|
||||
return undefined;
|
||||
/** @deprecated */
|
||||
readFindTextSync(): string {
|
||||
return this.findText;
|
||||
}
|
||||
|
||||
writeFindText(text: string): void { }
|
||||
|
||||
writeResources(resources: URI[]): void {
|
||||
this._internalResourcesClipboard = resources;
|
||||
}
|
||||
|
||||
readResources(): URI[] {
|
||||
return this._internalResourcesClipboard || [];
|
||||
}
|
||||
|
||||
hasResources(): boolean {
|
||||
return this._internalResourcesClipboard !== undefined && this._internalResourcesClipboard.length > 0;
|
||||
/** @deprecated */
|
||||
writeFindTextSync(text: string): void {
|
||||
this.findText = text;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,30 +22,38 @@ export interface IClipboardService {
|
|||
*/
|
||||
readText(type?: string): Promise<string>;
|
||||
|
||||
readTextSync(): string | undefined;
|
||||
|
||||
/**
|
||||
* Reads text from the system find pasteboard.
|
||||
*/
|
||||
readFindText(): string;
|
||||
readFindText(): Promise<string>;
|
||||
|
||||
/**
|
||||
* Writes text to the system find pasteboard.
|
||||
*/
|
||||
writeFindText(text: string): void;
|
||||
writeFindText(text: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* Writes resources to the system clipboard.
|
||||
*/
|
||||
writeResources(resources: URI[]): void;
|
||||
writeResources(resources: URI[]): Promise<void>;
|
||||
|
||||
/**
|
||||
* Reads resources from the system clipboard.
|
||||
*/
|
||||
readResources(): URI[];
|
||||
readResources(): Promise<URI[]>;
|
||||
|
||||
/**
|
||||
* Find out if resources are copied to the clipboard.
|
||||
*/
|
||||
hasResources(): boolean;
|
||||
hasResources(): Promise<boolean>;
|
||||
|
||||
|
||||
/** @deprecated */
|
||||
readTextSync(): string | undefined;
|
||||
|
||||
/** @deprecated */
|
||||
readFindTextSync(): string;
|
||||
|
||||
/** @deprecated */
|
||||
writeFindTextSync(text: string): void;
|
||||
}
|
||||
|
|
|
@ -272,3 +272,12 @@ export function getFileNamesMessage(fileNamesOrResources: readonly (string | URI
|
|||
message.push('');
|
||||
return message.join('\n');
|
||||
}
|
||||
|
||||
export interface INativeOpenDialogOptions {
|
||||
forceNewWindow?: boolean;
|
||||
|
||||
defaultPath?: string;
|
||||
|
||||
telemetryEventName?: string;
|
||||
telemetryExtraData?: ITelemetryData;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import { isMacintosh } from 'vs/base/common/platform';
|
|||
import { dirname } from 'vs/base/common/path';
|
||||
import { normalizeNFC } from 'vs/base/common/normalization';
|
||||
import { exists } from 'vs/base/node/pfs';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/node/dialogs';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { localize } from 'vs/nls';
|
||||
import { WORKSPACE_FILTER } from 'vs/platform/workspaces/common/workspaces';
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/node/driver';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
|
||||
import * as electron from 'electron';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { remote } from 'electron';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { BaseWindowDriver } from 'vs/platform/driver/browser/baseDriver';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
|
||||
class WindowDriver extends BaseWindowDriver {
|
||||
|
||||
|
@ -32,7 +32,7 @@ class WindowDriver extends BaseWindowDriver {
|
|||
private async _click(selector: string, clickCount: number, offset?: { x: number, y: number }): Promise<void> {
|
||||
const { x, y } = await this._getElementXY(selector, offset);
|
||||
|
||||
const webContents: electron.WebContents = (electron as any).remote.getCurrentWebContents();
|
||||
const webContents = remote.getCurrentWebContents();
|
||||
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
|
||||
await timeout(10);
|
||||
|
||||
|
|
|
@ -4,19 +4,18 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, SaveDialogOptions, OpenDialogOptions, OpenDialogReturnValue, SaveDialogReturnValue, CrashReporterStartOptions } from 'electron';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/node/dialogs';
|
||||
import { MessageBoxOptions, MessageBoxReturnValue, OpenDevToolsOptions, SaveDialogOptions, OpenDialogOptions, OpenDialogReturnValue, SaveDialogReturnValue, CrashReporterStartOptions } from 'vs/base/parts/sandbox/common/electronTypes';
|
||||
import { IOpenedWindow, IWindowOpenable, IOpenEmptyWindowOptions, INativeOpenWindowOptions } from 'vs/platform/windows/common/windows';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { INativeOpenWindowOptions, IOpenedWindow } from 'vs/platform/windows/node/window';
|
||||
|
||||
export const IElectronService = createDecorator<IElectronService>('electronService');
|
||||
|
||||
export interface IElectronService {
|
||||
export interface ICommonElectronService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
// Properties
|
||||
readonly windowId: number;
|
||||
|
||||
// Events
|
||||
readonly onWindowOpen: Event<number>;
|
||||
|
||||
|
@ -61,6 +60,16 @@ export interface IElectronService {
|
|||
setDocumentEdited(edited: boolean): Promise<void>;
|
||||
openExternal(url: string): Promise<boolean>;
|
||||
updateTouchBar(items: ISerializableCommandAction[][]): Promise<void>;
|
||||
moveItemToTrash(fullPath: string, deleteOnFail?: boolean): Promise<boolean>;
|
||||
|
||||
// clipboard
|
||||
readClipboardText(type?: 'selection' | 'clipboard'): Promise<string>;
|
||||
writeClipboardText(text: string, type?: 'selection' | 'clipboard'): Promise<void>;
|
||||
readClipboardFindText(): Promise<string>;
|
||||
writeClipboardFindText(text: string): Promise<void>;
|
||||
writeClipboardBuffer(format: string, buffer: Uint8Array, type?: 'selection' | 'clipboard'): Promise<void>;
|
||||
readClipboardBuffer(format: string): Promise<Uint8Array>;
|
||||
hasClipboard(format: string, type?: 'selection' | 'clipboard'): Promise<boolean>;
|
||||
|
||||
// macOS Touchbar
|
||||
newWindowTab(): Promise<void>;
|
|
@ -5,13 +5,13 @@
|
|||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IWindowsMainService, ICodeWindow } from 'vs/platform/windows/electron-main/windows';
|
||||
import { MessageBoxOptions, MessageBoxReturnValue, shell, OpenDevToolsOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, CrashReporterStartOptions, crashReporter, Menu, BrowserWindow, app } from 'electron';
|
||||
import { INativeOpenWindowOptions, IOpenedWindow, OpenContext } from 'vs/platform/windows/node/window';
|
||||
import { MessageBoxOptions, MessageBoxReturnValue, shell, OpenDevToolsOptions, SaveDialogOptions, SaveDialogReturnValue, OpenDialogOptions, OpenDialogReturnValue, CrashReporterStartOptions, crashReporter, Menu, BrowserWindow, app, clipboard } from 'electron';
|
||||
import { OpenContext } from 'vs/platform/windows/node/window';
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
import { IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/node/dialogs';
|
||||
import { IOpenedWindow, INativeOpenWindowOptions, IWindowOpenable, IOpenEmptyWindowOptions } from 'vs/platform/windows/common/windows';
|
||||
import { INativeOpenDialogOptions } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { ICommonElectronService } from 'vs/platform/electron/common/electron';
|
||||
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { AddFirstParameterToFunctions } from 'vs/base/common/types';
|
||||
|
@ -23,9 +23,9 @@ import { createDecorator } from 'vs/platform/instantiation/common/instantiation'
|
|||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
|
||||
|
||||
export interface IElectronMainService extends AddFirstParameterToFunctions<IElectronService, Promise<unknown> /* only methods, not events */, number | undefined /* window ID */> { }
|
||||
export interface IElectronMainService extends AddFirstParameterToFunctions<ICommonElectronService, Promise<unknown> /* only methods, not events */, number | undefined /* window ID */> { }
|
||||
|
||||
export const IElectronMainService = createDecorator<IElectronService>('electronMainService');
|
||||
export const IElectronMainService = createDecorator<IElectronMainService>('electronMainService');
|
||||
|
||||
export class ElectronMainService implements IElectronMainService {
|
||||
|
||||
|
@ -41,6 +41,12 @@ export class ElectronMainService implements IElectronMainService {
|
|||
) {
|
||||
}
|
||||
|
||||
//#region Properties
|
||||
|
||||
get windowId(): never { throw new Error('Not implemented in electron-main'); }
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Events
|
||||
|
||||
readonly onWindowOpen: Event<number> = Event.filter(Event.fromNodeEventEmitter(app, 'browser-window-created', (_, window: BrowserWindow) => window.id), windowId => !!this.windowsMainService.getWindowById(windowId));
|
||||
|
@ -293,6 +299,43 @@ export class ElectronMainService implements IElectronMainService {
|
|||
}
|
||||
}
|
||||
|
||||
async moveItemToTrash(windowId: number | undefined, fullPath: string): Promise<boolean> {
|
||||
return shell.moveItemToTrash(fullPath);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
//#region clipboard
|
||||
|
||||
async readClipboardText(windowId: number | undefined, type?: 'selection' | 'clipboard'): Promise<string> {
|
||||
return clipboard.readText(type);
|
||||
}
|
||||
|
||||
async writeClipboardText(windowId: number | undefined, text: string, type?: 'selection' | 'clipboard'): Promise<void> {
|
||||
return clipboard.writeText(text, type);
|
||||
}
|
||||
|
||||
async readClipboardFindText(windowId: number | undefined,): Promise<string> {
|
||||
return clipboard.readFindText();
|
||||
}
|
||||
|
||||
async writeClipboardFindText(windowId: number | undefined, text: string): Promise<void> {
|
||||
return clipboard.writeFindText(text);
|
||||
}
|
||||
|
||||
async writeClipboardBuffer(windowId: number | undefined, format: string, buffer: Uint8Array, type?: 'selection' | 'clipboard'): Promise<void> {
|
||||
return clipboard.writeBuffer(format, buffer as Buffer, type);
|
||||
}
|
||||
|
||||
async readClipboardBuffer(windowId: number | undefined, format: string): Promise<Uint8Array> {
|
||||
return clipboard.readBuffer(format);
|
||||
}
|
||||
|
||||
async hasClipboard(windowId: number | undefined, format: string, type?: 'selection' | 'clipboard'): Promise<boolean> {
|
||||
return clipboard.has(format, type);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region macOS Touchbar
|
||||
|
|
33
src/vs/platform/electron/electron-sandbox/electron.ts
Normal file
33
src/vs/platform/electron/electron-sandbox/electron.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommonElectronService } from 'vs/platform/electron/common/electron';
|
||||
import { IMainProcessService } from 'vs/platform/ipc/electron-sandbox/mainProcessService';
|
||||
import { createChannelSender } from 'vs/base/parts/ipc/common/ipc';
|
||||
|
||||
export const IElectronService = createDecorator<IElectronService>('electronService');
|
||||
|
||||
export interface IElectronService extends ICommonElectronService { }
|
||||
|
||||
export class ElectronService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
constructor(
|
||||
readonly windowId: number,
|
||||
@IMainProcessService mainProcessService: IMainProcessService
|
||||
) {
|
||||
return createChannelSender<IElectronService>(mainProcessService.getChannel('electron'), {
|
||||
context: windowId,
|
||||
properties: (() => {
|
||||
const properties = new Map<string, unknown>();
|
||||
properties.set('windowId', windowId);
|
||||
|
||||
return properties;
|
||||
})()
|
||||
});
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
import * as assert from 'assert';
|
||||
import { firstIndex } from 'vs/base/common/arrays';
|
||||
import { localize } from 'vs/nls';
|
||||
import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/node/files';
|
||||
import { MIN_MAX_MEMORY_SIZE_MB } from 'vs/platform/files/common/files';
|
||||
import { parseArgs, ErrorReporter, OPTIONS, ParsedArgs } from 'vs/platform/environment/node/argv';
|
||||
|
||||
function parseAndValidate(cmdLineArgs: string[], reportWarnings: boolean): ParsedArgs {
|
||||
|
|
|
@ -362,10 +362,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||
}
|
||||
const { id, uuid } = extension ? extension.identifier : <IExtensionIdentifier>arg1;
|
||||
let query = new Query()
|
||||
.withFlags(Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties, Flags.ExcludeNonValidated)
|
||||
.withFlags(Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
.withPage(1, 1)
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
|
||||
.withFilter(FilterType.ExcludeWithFlags, flagsToString(Flags.Unpublished));
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code');
|
||||
|
||||
if (uuid) {
|
||||
query = query.withFilter(FilterType.ExtensionId, uuid);
|
||||
|
@ -426,8 +425,7 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||
let query = new Query()
|
||||
.withFlags(Flags.IncludeLatestVersionOnly, Flags.IncludeAssetUri, Flags.IncludeStatistics, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
.withPage(1, pageSize)
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
|
||||
.withFilter(FilterType.ExcludeWithFlags, flagsToString(Flags.Unpublished));
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code');
|
||||
|
||||
if (text) {
|
||||
// Use category filter instead of "category:themes"
|
||||
|
@ -484,6 +482,11 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||
}
|
||||
|
||||
private queryGallery(query: Query, token: CancellationToken): Promise<{ galleryExtensions: IRawGalleryExtension[], total: number; }> {
|
||||
// Always exclude non validated and unpublished extensions
|
||||
query = query
|
||||
.withFlags(query.flags, Flags.ExcludeNonValidated)
|
||||
.withFilter(FilterType.ExcludeWithFlags, flagsToString(Flags.Unpublished));
|
||||
|
||||
if (!this.isEnabled()) {
|
||||
return Promise.reject(new Error('No extension gallery service configured.'));
|
||||
}
|
||||
|
@ -602,10 +605,9 @@ export class ExtensionGalleryService implements IExtensionGalleryService {
|
|||
|
||||
getAllVersions(extension: IGalleryExtension, compatible: boolean): Promise<IGalleryExtensionVersion[]> {
|
||||
let query = new Query()
|
||||
.withFlags(Flags.IncludeVersions, Flags.IncludeFiles, Flags.IncludeVersionProperties, Flags.ExcludeNonValidated)
|
||||
.withFlags(Flags.IncludeVersions, Flags.IncludeFiles, Flags.IncludeVersionProperties)
|
||||
.withPage(1, 1)
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code')
|
||||
.withFilter(FilterType.ExcludeWithFlags, flagsToString(Flags.Unpublished));
|
||||
.withFilter(FilterType.Target, 'Microsoft.VisualStudio.Code');
|
||||
|
||||
if (extension.identifier.uuid) {
|
||||
query = query.withFilter(FilterType.ExtensionId, extension.identifier.uuid);
|
||||
|
|
|
@ -824,7 +824,6 @@ export function etag(stat: { mtime: number | undefined, size: number | undefined
|
|||
return stat.mtime.toString(29) + stat.size.toString(31);
|
||||
}
|
||||
|
||||
|
||||
export function whenProviderRegistered(file: URI, fileService: IFileService): Promise<void> {
|
||||
if (fileService.canHandleResource(URI.from({ scheme: file.scheme }))) {
|
||||
return Promise.resolve();
|
||||
|
@ -838,3 +837,9 @@ export function whenProviderRegistered(file: URI, fileService: IFileService): Pr
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Desktop only: limits for memory sizes
|
||||
*/
|
||||
export const MIN_MAX_MEMORY_SIZE_MB = 2048;
|
||||
export const FALLBACK_MAX_MEMORY_SIZE_MB = 4096;
|
||||
|
|
|
@ -3,15 +3,24 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { shell } from 'electron';
|
||||
import { DiskFileSystemProvider as NodeDiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
import { DiskFileSystemProvider as NodeDiskFileSystemProvider, IDiskFileSystemProviderOptions } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
import { FileDeleteOptions, FileSystemProviderCapabilities } from 'vs/platform/files/common/files';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { localize } from 'vs/nls';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
|
||||
export class DiskFileSystemProvider extends NodeDiskFileSystemProvider {
|
||||
|
||||
constructor(
|
||||
logService: ILogService,
|
||||
private electronService: IElectronService,
|
||||
options?: IDiskFileSystemProviderOptions
|
||||
) {
|
||||
super(logService, options);
|
||||
}
|
||||
|
||||
get capabilities(): FileSystemProviderCapabilities {
|
||||
if (!this._capabilities) {
|
||||
this._capabilities = super.capabilities | FileSystemProviderCapabilities.Trash;
|
||||
|
@ -25,9 +34,9 @@ export class DiskFileSystemProvider extends NodeDiskFileSystemProvider {
|
|||
return super.doDelete(filePath, opts);
|
||||
}
|
||||
|
||||
const result = shell.moveItemToTrash(filePath);
|
||||
const result = await this.electronService.moveItemToTrash(filePath);
|
||||
if (!result) {
|
||||
throw new Error(isWindows ? localize('binFailed', "Failed to move '{0}' to the recycle bin", basename(filePath)) : localize('trashFailed', "Failed to move '{0}' to the trash", basename(filePath)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as assert from 'assert';
|
|||
import { tmpdir } from 'os';
|
||||
import { FileService } from 'vs/platform/files/common/fileService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/node/diskFileSystemProvider';
|
||||
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { join, basename, dirname, posix } from 'vs/base/common/path';
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Client } from 'vs/base/parts/ipc/electron-browser/ipc.electron-browser';
|
||||
import { Client } from 'vs/base/parts/ipc/electron-sandbox/ipc.electron-sandbox';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const IMainProcessService = createDecorator<IMainProcessService>('mainProcessService');
|
||||
|
|
@ -3,10 +3,6 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const IIssueService = createDecorator<IIssueService>('issueService');
|
||||
|
||||
// Since data sent through the service is serialized to JSON, functions will be lost, so Color objects
|
||||
// should not be sent as their 'toString' method will be stripped. Instead convert to strings before sending.
|
||||
export interface WindowStyles {
|
||||
|
@ -91,7 +87,7 @@ export interface ProcessExplorerData extends WindowData {
|
|||
styles: ProcessExplorerStyles;
|
||||
}
|
||||
|
||||
export interface IIssueService {
|
||||
export interface ICommonIssueService {
|
||||
_serviceBrand: undefined;
|
||||
openReporter(data: IssueReporterData): Promise<void>;
|
||||
openProcessExplorer(data: ProcessExplorerData): Promise<void>;
|
|
@ -6,7 +6,7 @@
|
|||
import { localize } from 'vs/nls';
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import { parseArgs, OPTIONS } from 'vs/platform/environment/node/argv';
|
||||
import { IIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/node/issue';
|
||||
import { ICommonIssueService, IssueReporterData, IssueReporterFeatures, ProcessExplorerData } from 'vs/platform/issue/common/issue';
|
||||
import { BrowserWindow, ipcMain, screen, IpcMainEvent, Display, shell } from 'electron';
|
||||
import { ILaunchMainService } from 'vs/platform/launch/electron-main/launchMainService';
|
||||
import { PerformanceInfo, isRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
|
@ -18,10 +18,16 @@ import { ILogService } from 'vs/platform/log/common/log';
|
|||
import { IWindowState } from 'vs/platform/windows/electron-main/windows';
|
||||
import { listProcesses } from 'vs/base/node/ps';
|
||||
import { IDialogMainService } from 'vs/platform/dialogs/electron-main/dialogs';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
const DEFAULT_BACKGROUND_COLOR = '#1E1E1E';
|
||||
|
||||
export class IssueMainService implements IIssueService {
|
||||
export const IIssueMainService = createDecorator<IIssueMainService>('issueMainService');
|
||||
|
||||
export interface IIssueMainService extends ICommonIssueService { }
|
||||
|
||||
export class IssueMainService implements ICommonIssueService {
|
||||
_serviceBrand: undefined;
|
||||
_issueWindow: BrowserWindow | null = null;
|
||||
_issueParentWindow: BrowserWindow | null = null;
|
||||
|
@ -163,12 +169,11 @@ export class IssueMainService implements IIssueService {
|
|||
}
|
||||
});
|
||||
|
||||
ipcMain.on('windowsInfoRequest', (event: IpcMainEvent) => {
|
||||
ipcMain.on('vscode:windowsInfoRequest', (event: IpcMainEvent) => {
|
||||
this.launchMainService.getMainProcessInfo().then(info => {
|
||||
event.sender.send('vscode:windowsInfoResponse', info.windows);
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
openReporter(data: IssueReporterData): Promise<void> {
|
||||
|
@ -189,8 +194,8 @@ export class IssueMainService implements IIssueService {
|
|||
title: localize('issueReporter', "Issue Reporter"),
|
||||
backgroundColor: data.styles.backgroundColor || DEFAULT_BACKGROUND_COLOR,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
enableWebSQL: false
|
||||
preload: URI.parse(require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js')).fsPath,
|
||||
nodeIntegration: true
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -225,7 +230,7 @@ export class IssueMainService implements IIssueService {
|
|||
if (!this._processExplorerWindow) {
|
||||
this._processExplorerParentWindow = BrowserWindow.getFocusedWindow();
|
||||
if (this._processExplorerParentWindow) {
|
||||
const position = this.getWindowPosition(this._processExplorerParentWindow, 800, 300);
|
||||
const position = this.getWindowPosition(this._processExplorerParentWindow, 800, 500);
|
||||
this._processExplorerWindow = new BrowserWindow({
|
||||
skipTaskbar: true,
|
||||
resizable: true,
|
||||
|
@ -239,8 +244,8 @@ export class IssueMainService implements IIssueService {
|
|||
backgroundColor: data.styles.backgroundColor,
|
||||
title: localize('processExplorer', "Process Explorer"),
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
enableWebSQL: false
|
||||
preload: URI.parse(require.toUrl('vs/base/parts/sandbox/electron-browser/preload.js')).fsPath,
|
||||
nodeIntegration: true
|
||||
}
|
||||
});
|
||||
|
||||
|
|
11
src/vs/platform/issue/electron-sandbox/issue.ts
Normal file
11
src/vs/platform/issue/electron-sandbox/issue.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommonIssueService } from 'vs/platform/issue/common/issue';
|
||||
|
||||
export const IIssueService = createDecorator<IIssueService>('issueService');
|
||||
|
||||
export interface IIssueService extends ICommonIssueService { }
|
|
@ -3,14 +3,9 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export const IMenubarService = createDecorator<IMenubarService>('menubarService');
|
||||
|
||||
export interface IMenubarService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
export interface ICommonMenubarService {
|
||||
updateMenubar(windowId: number, menuData: IMenubarData): Promise<void>;
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
|||
import { mnemonicMenuLabel as baseMnemonicLabel } from 'vs/base/common/labels';
|
||||
import { IWindowsMainService, IWindowsCountChangedEvent } from 'vs/platform/windows/electron-main/windows';
|
||||
import { IWorkspacesHistoryMainService } from 'vs/platform/workspaces/electron-main/workspacesHistoryMainService';
|
||||
import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, IMenubarMenu, isMenubarMenuItemUriAction } from 'vs/platform/menubar/node/menubar';
|
||||
import { IMenubarData, IMenubarKeybinding, MenubarMenuItem, isMenubarMenuItemSeparator, isMenubarMenuItemSubmenu, isMenubarMenuItemAction, IMenubarMenu, isMenubarMenuItemUriAction } from 'vs/platform/menubar/common/menubar';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IStateService } from 'vs/platform/state/node/state';
|
||||
import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
|
|
|
@ -3,13 +3,19 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IMenubarService, IMenubarData } from 'vs/platform/menubar/node/menubar';
|
||||
import { ICommonMenubarService, IMenubarData } from 'vs/platform/menubar/common/menubar';
|
||||
import { Menubar } from 'vs/platform/menubar/electron-main/menubar';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
|
||||
|
||||
export class MenubarMainService implements IMenubarService {
|
||||
export const IMenubarMainService = createDecorator<IMenubarMainService>('menubarMainService');
|
||||
|
||||
export interface IMenubarMainService extends ICommonMenubarService {
|
||||
_serviceBrand: undefined;
|
||||
}
|
||||
|
||||
export class MenubarMainService implements IMenubarMainService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
|
||||
|
|
13
src/vs/platform/menubar/electron-sandbox/menubar.ts
Normal file
13
src/vs/platform/menubar/electron-sandbox/menubar.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ICommonMenubarService } from 'vs/platform/menubar/common/menubar';
|
||||
|
||||
export const IMenubarService = createDecorator<IMenubarService>('menubarService');
|
||||
|
||||
export interface IMenubarService extends ICommonMenubarService {
|
||||
_serviceBrand: undefined;
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export const IUndoRedoService = createDecorator<IUndoRedoService>('undoRedoService');
|
||||
|
||||
|
@ -28,6 +29,13 @@ export interface IWorkspaceUndoRedoElement {
|
|||
undo(): Promise<void> | void;
|
||||
redo(): Promise<void> | void;
|
||||
split(): IResourceUndoRedoElement[];
|
||||
|
||||
/**
|
||||
* If implemented, will be invoked before calling `undo()` or `redo()`.
|
||||
* This is a good place to prepare everything such that the calls to `undo()` or `redo()` are synchronous.
|
||||
* If a disposable is returned, it will be invoked to clean things up.
|
||||
*/
|
||||
prepareUndoRedo?(): Promise<IDisposable> | IDisposable | void;
|
||||
}
|
||||
|
||||
export type IUndoRedoElement = IResourceUndoRedoElement | IWorkspaceUndoRedoElement;
|
||||
|
|
|
@ -12,6 +12,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
|||
import Severity from 'vs/base/common/severity';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
function uriGetComparisonKey(resource: URI): string {
|
||||
return resource.toString();
|
||||
|
@ -76,7 +77,7 @@ class RemovedResources {
|
|||
|
||||
let messages: string[] = [];
|
||||
if (externalRemoval.length > 0) {
|
||||
messages.push(nls.localize('externalRemoval', "The following files have been closed: {0}.", externalRemoval.join(', ')));
|
||||
messages.push(nls.localize('externalRemoval', "The following files have been closed and modified on disk: {0}.", externalRemoval.join(', ')));
|
||||
}
|
||||
if (noParallelUniverses.length > 0) {
|
||||
messages.push(nls.localize('noParallelUniverses', "The following files have been modified in an incompatible way: {0}.", noParallelUniverses.join(', ')));
|
||||
|
@ -154,11 +155,13 @@ class ResourceEditStack {
|
|||
public resource: URI;
|
||||
public past: StackElement[];
|
||||
public future: StackElement[];
|
||||
public locked: boolean;
|
||||
|
||||
constructor(resource: URI) {
|
||||
this.resource = resource;
|
||||
this.past = [];
|
||||
this.future = [];
|
||||
this.locked = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,55 +366,135 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
this._notificationService.error(err);
|
||||
}
|
||||
|
||||
private _safeInvoke(element: StackElement, invoke: () => Promise<void> | void): Promise<void> | void {
|
||||
private _acquireLocks(affectedEditStacks: ResourceEditStack[]): () => void {
|
||||
// first, check if all locks can be acquired
|
||||
for (const editStack of affectedEditStacks) {
|
||||
if (editStack.locked) {
|
||||
throw new Error('Cannot acquire edit stack lock');
|
||||
}
|
||||
}
|
||||
|
||||
// can acquire all locks
|
||||
for (const editStack of affectedEditStacks) {
|
||||
editStack.locked = true;
|
||||
}
|
||||
|
||||
return () => {
|
||||
// release all locks
|
||||
for (const editStack of affectedEditStacks) {
|
||||
editStack.locked = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private _safeInvokeWithLocks(element: StackElement, invoke: () => Promise<void> | void, affectedEditStacks: ResourceEditStack[], cleanup: IDisposable = Disposable.None): Promise<void> | void {
|
||||
const releaseLocks = this._acquireLocks(affectedEditStacks);
|
||||
|
||||
let result: Promise<void> | void;
|
||||
try {
|
||||
result = invoke();
|
||||
} catch (err) {
|
||||
releaseLocks();
|
||||
cleanup.dispose();
|
||||
return this._onError(err, element);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return result.then(undefined, (err) => this._onError(err, element));
|
||||
// result is Promise<void>
|
||||
return result.then(
|
||||
() => {
|
||||
releaseLocks();
|
||||
cleanup.dispose();
|
||||
},
|
||||
(err) => {
|
||||
releaseLocks();
|
||||
cleanup.dispose();
|
||||
return this._onError(err, element);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
// result is void
|
||||
releaseLocks();
|
||||
cleanup.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private _workspaceUndo(resource: URI, element: WorkspaceStackElement): Promise<void> | void {
|
||||
private async _invokePrepare(element: WorkspaceStackElement): Promise<IDisposable> {
|
||||
if (typeof element.actual.prepareUndoRedo === 'undefined') {
|
||||
return Disposable.None;
|
||||
}
|
||||
const result = element.actual.prepareUndoRedo();
|
||||
if (typeof result === 'undefined') {
|
||||
return Disposable.None;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private _getAffectedEditStacks(element: WorkspaceStackElement): ResourceEditStack[] {
|
||||
const affectedEditStacks: ResourceEditStack[] = [];
|
||||
for (const strResource of element.strResources) {
|
||||
affectedEditStacks.push(this._editStacks.get(strResource)!);
|
||||
}
|
||||
return affectedEditStacks;
|
||||
}
|
||||
|
||||
private _checkWorkspaceUndo(resource: URI, element: WorkspaceStackElement, affectedEditStacks: ResourceEditStack[], checkInvalidatedResources: boolean): WorkspaceVerificationError | null {
|
||||
if (element.removedResources) {
|
||||
this._splitPastWorkspaceElement(element, element.removedResources);
|
||||
const message = nls.localize('cannotWorkspaceUndo', "Could not undo '{0}' across all files. {1}", element.label, element.removedResources.createMessage());
|
||||
this._notificationService.info(message);
|
||||
return this.undo(resource);
|
||||
return new WorkspaceVerificationError(this.undo(resource));
|
||||
}
|
||||
if (element.invalidatedResources) {
|
||||
if (checkInvalidatedResources && element.invalidatedResources) {
|
||||
this._splitPastWorkspaceElement(element, element.invalidatedResources);
|
||||
const message = nls.localize('cannotWorkspaceUndo', "Could not undo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage());
|
||||
this._notificationService.info(message);
|
||||
return this.undo(resource);
|
||||
return new WorkspaceVerificationError(this.undo(resource));
|
||||
}
|
||||
|
||||
// this must be the last past element in all the impacted resources!
|
||||
let affectedEditStacks: ResourceEditStack[] = [];
|
||||
for (const strResource of element.strResources) {
|
||||
affectedEditStacks.push(this._editStacks.get(strResource)!);
|
||||
}
|
||||
|
||||
let cannotUndoDueToResources: URI[] = [];
|
||||
const cannotUndoDueToResources: URI[] = [];
|
||||
for (const editStack of affectedEditStacks) {
|
||||
if (editStack.past.length === 0 || editStack.past[editStack.past.length - 1] !== element) {
|
||||
cannotUndoDueToResources.push(editStack.resource);
|
||||
}
|
||||
}
|
||||
|
||||
if (cannotUndoDueToResources.length > 0) {
|
||||
this._splitPastWorkspaceElement(element, null);
|
||||
const paths = cannotUndoDueToResources.map(r => r.scheme === Schemas.file ? r.fsPath : r.path);
|
||||
const message = nls.localize('cannotWorkspaceUndoDueToChanges', "Could not undo '{0}' across all files because changes were made to {1}", element.label, paths.join(', '));
|
||||
this._notificationService.info(message);
|
||||
return this.undo(resource);
|
||||
return new WorkspaceVerificationError(this.undo(resource));
|
||||
}
|
||||
|
||||
return this._dialogService.show(
|
||||
const cannotLockDueToResources: URI[] = [];
|
||||
for (const editStack of affectedEditStacks) {
|
||||
if (editStack.locked) {
|
||||
cannotLockDueToResources.push(editStack.resource);
|
||||
}
|
||||
}
|
||||
if (cannotLockDueToResources.length > 0) {
|
||||
this._splitPastWorkspaceElement(element, null);
|
||||
const paths = cannotLockDueToResources.map(r => r.scheme === Schemas.file ? r.fsPath : r.path);
|
||||
const message = nls.localize('cannotWorkspaceUndoDueToInProgressUndoRedo', "Could not undo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, paths.join(', '));
|
||||
this._notificationService.info(message);
|
||||
return new WorkspaceVerificationError(this.undo(resource));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private _workspaceUndo(resource: URI, element: WorkspaceStackElement): Promise<void> | void {
|
||||
const affectedEditStacks = this._getAffectedEditStacks(element);
|
||||
const verificationError = this._checkWorkspaceUndo(resource, element, affectedEditStacks, /*invalidated resources will be checked after the prepare call*/false);
|
||||
if (verificationError) {
|
||||
return verificationError.returnValue;
|
||||
}
|
||||
return this._confirmAndExecuteWorkspaceUndo(resource, element, affectedEditStacks);
|
||||
}
|
||||
|
||||
private async _confirmAndExecuteWorkspaceUndo(resource: URI, element: WorkspaceStackElement, affectedEditStacks: ResourceEditStack[]): Promise<void> {
|
||||
const result = await this._dialogService.show(
|
||||
Severity.Info,
|
||||
nls.localize('confirmWorkspace', "Would you like to undo '{0}' across all files?", element.label),
|
||||
[
|
||||
|
@ -422,21 +505,47 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
{
|
||||
cancelId: 2
|
||||
}
|
||||
).then((result) => {
|
||||
if (result.choice === 2) {
|
||||
// cancel
|
||||
return;
|
||||
} else if (result.choice === 0) {
|
||||
for (const editStack of affectedEditStacks) {
|
||||
editStack.past.pop();
|
||||
editStack.future.push(element);
|
||||
}
|
||||
return this._safeInvoke(element, () => element.actual.undo());
|
||||
} else {
|
||||
this._splitPastWorkspaceElement(element, null);
|
||||
return this.undo(resource);
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
if (result.choice === 2) {
|
||||
// choice: cancel
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.choice === 1) {
|
||||
// choice: undo this file
|
||||
this._splitPastWorkspaceElement(element, null);
|
||||
return this.undo(resource);
|
||||
}
|
||||
|
||||
// choice: undo in all files
|
||||
|
||||
// At this point, it is possible that the element has been made invalid in the meantime (due to the confirmation await)
|
||||
const verificationError1 = this._checkWorkspaceUndo(resource, element, affectedEditStacks, /*invalidated resources will be checked after the prepare call*/false);
|
||||
if (verificationError1) {
|
||||
return verificationError1.returnValue;
|
||||
}
|
||||
|
||||
// prepare
|
||||
let cleanup: IDisposable;
|
||||
try {
|
||||
cleanup = await this._invokePrepare(element);
|
||||
} catch (err) {
|
||||
return this._onError(err, element);
|
||||
}
|
||||
|
||||
// At this point, it is possible that the element has been made invalid in the meantime (due to the prepare await)
|
||||
const verificationError2 = this._checkWorkspaceUndo(resource, element, affectedEditStacks, /*now also check that there are no more invalidated resources*/true);
|
||||
if (verificationError2) {
|
||||
cleanup.dispose();
|
||||
return verificationError2.returnValue;
|
||||
}
|
||||
|
||||
for (const editStack of affectedEditStacks) {
|
||||
editStack.past.pop();
|
||||
editStack.future.push(element);
|
||||
}
|
||||
return this._safeInvokeWithLocks(element, () => element.actual.undo(), affectedEditStacks, cleanup);
|
||||
}
|
||||
|
||||
private _resourceUndo(editStack: ResourceEditStack, element: ResourceStackElement): Promise<void> | void {
|
||||
|
@ -446,9 +555,14 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
editStack.future = [];
|
||||
return;
|
||||
}
|
||||
if (editStack.locked) {
|
||||
const message = nls.localize('cannotResourceUndoDueToInProgressUndoRedo', "Could not undo '{0}' because there is already an undo or redo operation running.", element.label);
|
||||
this._notificationService.info(message);
|
||||
return;
|
||||
}
|
||||
editStack.past.pop();
|
||||
editStack.future.push(element);
|
||||
return this._safeInvoke(element, () => element.actual.undo());
|
||||
return this._safeInvokeWithLocks(element, () => element.actual.undo(), [editStack]);
|
||||
}
|
||||
|
||||
public undo(resource: URI): Promise<void> | void {
|
||||
|
@ -479,46 +593,82 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
return false;
|
||||
}
|
||||
|
||||
private _workspaceRedo(resource: URI, element: WorkspaceStackElement): Promise<void> | void {
|
||||
private _checkWorkspaceRedo(resource: URI, element: WorkspaceStackElement, affectedEditStacks: ResourceEditStack[], checkInvalidatedResources: boolean): WorkspaceVerificationError | null {
|
||||
if (element.removedResources) {
|
||||
this._splitFutureWorkspaceElement(element, element.removedResources);
|
||||
const message = nls.localize('cannotWorkspaceRedo', "Could not redo '{0}' across all files. {1}", element.label, element.removedResources.createMessage());
|
||||
this._notificationService.info(message);
|
||||
return this.redo(resource);
|
||||
return new WorkspaceVerificationError(this.redo(resource));
|
||||
}
|
||||
if (element.invalidatedResources) {
|
||||
if (checkInvalidatedResources && element.invalidatedResources) {
|
||||
this._splitFutureWorkspaceElement(element, element.invalidatedResources);
|
||||
const message = nls.localize('cannotWorkspaceRedo', "Could not redo '{0}' across all files. {1}", element.label, element.invalidatedResources.createMessage());
|
||||
this._notificationService.info(message);
|
||||
return this.redo(resource);
|
||||
return new WorkspaceVerificationError(this.redo(resource));
|
||||
}
|
||||
|
||||
// this must be the last future element in all the impacted resources!
|
||||
let affectedEditStacks: ResourceEditStack[] = [];
|
||||
for (const strResource of element.strResources) {
|
||||
affectedEditStacks.push(this._editStacks.get(strResource)!);
|
||||
}
|
||||
|
||||
let cannotRedoDueToResources: URI[] = [];
|
||||
const cannotRedoDueToResources: URI[] = [];
|
||||
for (const editStack of affectedEditStacks) {
|
||||
if (editStack.future.length === 0 || editStack.future[editStack.future.length - 1] !== element) {
|
||||
cannotRedoDueToResources.push(editStack.resource);
|
||||
}
|
||||
}
|
||||
|
||||
if (cannotRedoDueToResources.length > 0) {
|
||||
this._splitFutureWorkspaceElement(element, null);
|
||||
const paths = cannotRedoDueToResources.map(r => r.scheme === Schemas.file ? r.fsPath : r.path);
|
||||
const message = nls.localize('cannotWorkspaceRedoDueToChanges', "Could not redo '{0}' across all files because changes were made to {1}", element.label, paths.join(', '));
|
||||
this._notificationService.info(message);
|
||||
return this.redo(resource);
|
||||
return new WorkspaceVerificationError(this.redo(resource));
|
||||
}
|
||||
|
||||
const cannotLockDueToResources: URI[] = [];
|
||||
for (const editStack of affectedEditStacks) {
|
||||
if (editStack.locked) {
|
||||
cannotLockDueToResources.push(editStack.resource);
|
||||
}
|
||||
}
|
||||
if (cannotLockDueToResources.length > 0) {
|
||||
this._splitFutureWorkspaceElement(element, null);
|
||||
const paths = cannotLockDueToResources.map(r => r.scheme === Schemas.file ? r.fsPath : r.path);
|
||||
const message = nls.localize('cannotWorkspaceRedoDueToInProgressUndoRedo', "Could not redo '{0}' across all files because there is already an undo or redo operation running on {1}", element.label, paths.join(', '));
|
||||
this._notificationService.info(message);
|
||||
return new WorkspaceVerificationError(this.redo(resource));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private _workspaceRedo(resource: URI, element: WorkspaceStackElement): Promise<void> | void {
|
||||
const affectedEditStacks = this._getAffectedEditStacks(element);
|
||||
const verificationError = this._checkWorkspaceRedo(resource, element, affectedEditStacks, /*invalidated resources will be checked after the prepare call*/false);
|
||||
if (verificationError) {
|
||||
return verificationError.returnValue;
|
||||
}
|
||||
return this._executeWorkspaceRedo(resource, element, affectedEditStacks);
|
||||
}
|
||||
|
||||
private async _executeWorkspaceRedo(resource: URI, element: WorkspaceStackElement, affectedEditStacks: ResourceEditStack[]): Promise<void> {
|
||||
// prepare
|
||||
let cleanup: IDisposable;
|
||||
try {
|
||||
cleanup = await this._invokePrepare(element);
|
||||
} catch (err) {
|
||||
return this._onError(err, element);
|
||||
}
|
||||
|
||||
// At this point, it is possible that the element has been made invalid in the meantime (due to the prepare await)
|
||||
const verificationError = this._checkWorkspaceRedo(resource, element, affectedEditStacks, /*now also check that there are no more invalidated resources*/true);
|
||||
if (verificationError) {
|
||||
cleanup.dispose();
|
||||
return verificationError.returnValue;
|
||||
}
|
||||
|
||||
for (const editStack of affectedEditStacks) {
|
||||
editStack.future.pop();
|
||||
editStack.past.push(element);
|
||||
}
|
||||
return this._safeInvoke(element, () => element.actual.redo());
|
||||
return this._safeInvokeWithLocks(element, () => element.actual.redo(), affectedEditStacks, cleanup);
|
||||
}
|
||||
|
||||
private _resourceRedo(editStack: ResourceEditStack, element: ResourceStackElement): Promise<void> | void {
|
||||
|
@ -528,9 +678,14 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
editStack.future = [];
|
||||
return;
|
||||
}
|
||||
if (editStack.locked) {
|
||||
const message = nls.localize('cannotResourceRedoDueToInProgressUndoRedo', "Could not redo '{0}' because there is already an undo or redo operation running.", element.label);
|
||||
this._notificationService.info(message);
|
||||
return;
|
||||
}
|
||||
editStack.future.pop();
|
||||
editStack.past.push(element);
|
||||
return this._safeInvoke(element, () => element.actual.redo());
|
||||
return this._safeInvokeWithLocks(element, () => element.actual.redo(), [editStack]);
|
||||
}
|
||||
|
||||
public redo(resource: URI): Promise<void> | void {
|
||||
|
@ -553,4 +708,8 @@ export class UndoRedoService implements IUndoRedoService {
|
|||
}
|
||||
}
|
||||
|
||||
class WorkspaceVerificationError {
|
||||
constructor(public readonly returnValue: Promise<void> | void) { }
|
||||
}
|
||||
|
||||
registerSingleton(IUndoRedoService, UndoRedoService);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { URI, UriComponents } from 'vs/base/common/uri';
|
|||
import { values } from 'vs/base/common/map';
|
||||
import { first } from 'vs/base/common/async';
|
||||
import { toDisposable, IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
|
||||
export abstract class AbstractURLService extends Disposable implements IURLService {
|
||||
|
||||
|
@ -27,3 +28,16 @@ export abstract class AbstractURLService extends Disposable implements IURLServi
|
|||
return toDisposable(() => this.handlers.delete(handler));
|
||||
}
|
||||
}
|
||||
|
||||
export class NativeURLService extends AbstractURLService {
|
||||
|
||||
create(options?: Partial<UriComponents>): URI {
|
||||
let { authority, path, query, fragment } = options ? options : { authority: undefined, path: undefined, query: undefined, fragment: undefined };
|
||||
|
||||
if (authority && path && path.indexOf('/') !== 0) {
|
||||
path = `/${path}`; // URI validation requires a path if there is an authority
|
||||
}
|
||||
|
||||
return URI.from({ scheme: product.urlProtocol, authority, path, query, fragment });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import product from 'vs/platform/product/common/product';
|
||||
import { AbstractURLService } from 'vs/platform/url/common/urlService';
|
||||
|
||||
export class URLService extends AbstractURLService {
|
||||
|
||||
create(options?: Partial<UriComponents>): URI {
|
||||
let { authority, path, query, fragment } = options ? options : { authority: undefined, path: undefined, query: undefined, fragment: undefined };
|
||||
|
||||
if (authority && path && path.indexOf('/') !== 0) {
|
||||
path = `/${path}`; // URI validation requires a path if there is an authority
|
||||
}
|
||||
|
||||
return URI.from({ scheme: product.urlProtocol, authority, path, query, fragment });
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { IUserDataSyncService, IUserDataSyncLogService, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IElectronService } from 'vs/platform/electron/node/electron';
|
||||
import { IElectronService } from 'vs/platform/electron/electron-sandbox/electron';
|
||||
import { UserDataAutoSyncService as BaseUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataAutoSyncService';
|
||||
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue