mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-13 15:35:20 +01:00
Merge branch 'main' into notebook/dev
This commit is contained in:
@@ -104,6 +104,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/common/**",
|
||||
"**/vs/base/test/common/**"
|
||||
@@ -139,6 +140,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/base/test/{common,browser}/**"
|
||||
@@ -212,6 +214,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/common/**",
|
||||
"**/vs/base/parts/*/common/**",
|
||||
@@ -225,6 +228,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser}/**",
|
||||
@@ -289,6 +293,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/base/parts/*/{common,browser}/**",
|
||||
@@ -311,6 +316,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/common/**",
|
||||
"**/vs/platform/*/common/**",
|
||||
@@ -334,6 +340,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/platform/*/{common,browser}/**",
|
||||
@@ -357,6 +364,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/common/**",
|
||||
"**/vs/platform/*/common/**",
|
||||
@@ -383,6 +391,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/platform/*/{common,browser}/**",
|
||||
@@ -397,6 +406,7 @@
|
||||
"restrictions": [
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"vs/nls",
|
||||
"**/vs/base/{common,browser}/**",
|
||||
"**/vs/base/test/{common,browser}/**",
|
||||
@@ -921,6 +931,7 @@
|
||||
"**/vs/**",
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"crypto",
|
||||
"vscode"
|
||||
]
|
||||
@@ -952,6 +963,7 @@
|
||||
"**/vs/**",
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"crypto",
|
||||
"xterm*"
|
||||
]
|
||||
@@ -962,6 +974,7 @@
|
||||
"**/vs/**",
|
||||
"assert",
|
||||
"sinon",
|
||||
"sinon-test",
|
||||
"crypto",
|
||||
"xterm*"
|
||||
]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"labels": {
|
||||
"L10N": {"assign": []},
|
||||
"VIM": {"assign": []},
|
||||
"accessibility": { "assign": ["isidorn"]},
|
||||
"accessibility": { "assign": ["isidorn", "sana-ajani"]},
|
||||
"api": {"assign": ["jrieken"]},
|
||||
"api-finalization": {"assign": []},
|
||||
"api-proposal": {"assign": ["jrieken"]},
|
||||
|
||||
@@ -409,5 +409,11 @@
|
||||
"gjsjohnmurray",
|
||||
"IllusionMH"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "label",
|
||||
"name": "*workspace-trust-docs",
|
||||
"action": "close",
|
||||
"comment": "This issue appears to be the result of the new workspace trust feature shipped in June 2021. This security-focused feature has major impact on the functionality of VS Code. Due to the volume of issues, we ask that you take some time to review our [comprehensive documentation](https://aka.ms/vscode-workspace-trust) on the feature. If your issue is still not resolved, please let us know."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -148,9 +148,9 @@ fsevents@~2.3.1:
|
||||
integrity sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==
|
||||
|
||||
glob-parent@^5.1.1, glob-parent@~5.1.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229"
|
||||
integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
|
||||
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
|
||||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
|
||||
+3
-3
@@ -1488,9 +1488,9 @@ node-fetch@^2.6.0:
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
normalize-url@^4.1.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
|
||||
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
|
||||
version "4.5.1"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
|
||||
integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
|
||||
|
||||
nth-check@~1.0.1:
|
||||
version "1.0.2"
|
||||
|
||||
@@ -11,7 +11,6 @@ export function activate() {
|
||||
});
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.classList.add('markdown-style');
|
||||
style.textContent = `
|
||||
.emptyMarkdownCell::before {
|
||||
content: "${document.documentElement.style.getPropertyValue('--notebook-cell-markup-empty-content')}";
|
||||
@@ -134,7 +133,10 @@ export function activate() {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
`;
|
||||
document.head.append(style);
|
||||
const template = document.createElement('template');
|
||||
template.classList.add('markdown-style');
|
||||
template.content.appendChild(style);
|
||||
document.head.appendChild(template);
|
||||
|
||||
return {
|
||||
renderOutputItem: (outputInfo: { text(): string }, element: HTMLElement) => {
|
||||
@@ -148,8 +150,12 @@ export function activate() {
|
||||
previewRoot.appendChild(defaultStyles.cloneNode(true));
|
||||
|
||||
// And then contributed styles
|
||||
for (const markdownStyleNode of document.getElementsByClassName('markdown-style')) {
|
||||
previewRoot.appendChild(markdownStyleNode.cloneNode(true));
|
||||
for (const element of document.getElementsByClassName('markdown-style')) {
|
||||
if (element instanceof HTMLTemplateElement) {
|
||||
previewRoot.appendChild(element.content.cloneNode(true));
|
||||
} else {
|
||||
previewRoot.appendChild(element.cloneNode(true));
|
||||
}
|
||||
}
|
||||
|
||||
previewNode = document.createElement('div');
|
||||
|
||||
@@ -18,16 +18,20 @@ export async function activate(ctx: {
|
||||
link.rel = 'stylesheet';
|
||||
link.classList.add('markdown-style');
|
||||
link.href = styleHref;
|
||||
document.head.append(link);
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.classList.add('markdown-style');
|
||||
style.textContent = `
|
||||
.katex-error {
|
||||
color: var(--vscode-editorError-foreground);
|
||||
}
|
||||
`;
|
||||
document.head.append(style);
|
||||
|
||||
// Put Everything into a template
|
||||
const styleTemplate = document.createElement('template');
|
||||
styleTemplate.classList.add('markdown-style');
|
||||
styleTemplate.content.appendChild(style);
|
||||
styleTemplate.content.appendChild(link);
|
||||
document.head.appendChild(styleTemplate);
|
||||
|
||||
const katex = require('@iktakahiro/markdown-it-katex');
|
||||
markdownItRenderer.extendMarkdownIt((md: markdownIt.MarkdownIt) => {
|
||||
|
||||
@@ -137,7 +137,7 @@ class DiagnosticSettings {
|
||||
const currentSettings = this.get(language);
|
||||
const newSettings = f(currentSettings);
|
||||
this._languageSettings.set(language, newSettings);
|
||||
return areLanguageDiagnosticSettingsEqual(currentSettings, newSettings);
|
||||
return !areLanguageDiagnosticSettingsEqual(currentSettings, newSettings);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -668,8 +668,7 @@ import { assertNoRpc } from '../utils';
|
||||
});
|
||||
});
|
||||
|
||||
// https://github.com/microsoft/vscode/issues/119826
|
||||
suite.skip('environmentVariableCollection', () => {
|
||||
suite('environmentVariableCollection', () => {
|
||||
test('should have collection variables apply to terminals immediately after setting', (done) => {
|
||||
// Text to match on before passing the test
|
||||
const expectedText = [
|
||||
|
||||
+6
-4
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.58.0",
|
||||
"distro": "3f43781e788d694f33746808cc5182852222f935",
|
||||
"distro": "f9acd3d731fc630bf6b665d551d5fa12ce0560e6",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -103,7 +103,8 @@
|
||||
"@types/minimist": "^1.2.1",
|
||||
"@types/mocha": "^8.2.0",
|
||||
"@types/node": "14.x",
|
||||
"@types/sinon": "^1.16.36",
|
||||
"@types/sinon": "^10.0.2",
|
||||
"@types/sinon-test": "^2.4.2",
|
||||
"@types/trusted-types": "^1.0.6",
|
||||
"@types/vscode-windows-registry": "^1.0.0",
|
||||
"@types/webpack": "^4.41.25",
|
||||
@@ -183,7 +184,8 @@
|
||||
"rcedit": "^1.1.0",
|
||||
"request": "^2.85.0",
|
||||
"rimraf": "^2.2.8",
|
||||
"sinon": "^1.17.2",
|
||||
"sinon": "^11.1.1",
|
||||
"sinon-test": "^3.1.0",
|
||||
"source-map": "0.6.1",
|
||||
"source-map-support": "^0.3.2",
|
||||
"style-loader": "^1.0.0",
|
||||
@@ -196,7 +198,7 @@
|
||||
"vinyl-fs": "^3.0.0",
|
||||
"vscode-debugprotocol": "1.47.0",
|
||||
"vscode-nls-dev": "^3.3.1",
|
||||
"vscode-telemetry-extractor": "^1.7.0",
|
||||
"vscode-telemetry-extractor": "^1.8.0",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-cli": "^3.3.12",
|
||||
"webpack-stream": "^5.2.1",
|
||||
|
||||
@@ -46,7 +46,7 @@ if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
:: Tests in the extension host
|
||||
|
||||
set ALL_PLATFORMS_API_TESTS_EXTRA_ARGS=--disable-telemetry --crash-reporter-directory=%VSCODECRASHDIR% --no-sandbox --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=%VSCODEUSERDATADIR%
|
||||
set ALL_PLATFORMS_API_TESTS_EXTRA_ARGS=--disable-telemetry --skip-welcome --crash-reporter-directory=%VSCODECRASHDIR% --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=%VSCODEUSERDATADIR%
|
||||
|
||||
call "%INTEGRATION_TEST_ELECTRON_PATH%" %~dp0\..\extensions\vscode-api-tests\testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=%~dp0\..\extensions\vscode-api-tests --extensionTestsPath=%~dp0\..\extensions\vscode-api-tests\out\singlefolder-tests %ALL_PLATFORMS_API_TESTS_EXTRA_ARGS%
|
||||
if %errorlevel% neq 0 exit /b %errorlevel%
|
||||
|
||||
@@ -62,7 +62,7 @@ after_suite
|
||||
|
||||
# Tests in the extension host
|
||||
|
||||
ALL_PLATFORMS_API_TESTS_EXTRA_ARGS="--disable-telemetry --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=$VSCODEUSERDATADIR"
|
||||
ALL_PLATFORMS_API_TESTS_EXTRA_ARGS="--disable-telemetry --skip-welcome --crash-reporter-directory=$VSCODECRASHDIR --no-cached-data --disable-updates --disable-keytar --disable-extensions --disable-workspace-trust --user-data-dir=$VSCODEUSERDATADIR"
|
||||
|
||||
"$INTEGRATION_TEST_ELECTRON_PATH" $LINUX_EXTRA_ARGS $ROOT/extensions/vscode-api-tests/testWorkspace --enable-proposed-api=vscode.vscode-api-tests --extensionDevelopmentPath=$ROOT/extensions/vscode-api-tests --extensionTestsPath=$ROOT/extensions/vscode-api-tests/out/singlefolder-tests $ALL_PLATFORMS_API_TESTS_EXTRA_ARGS
|
||||
after_suite
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
/**
|
||||
* A helper that will execute a provided function when the provided HTMLElement receives
|
||||
@@ -70,7 +71,7 @@ export const DataTransfers = {
|
||||
/**
|
||||
* Typically transfer type for copy/paste transfers.
|
||||
*/
|
||||
TEXT: 'text/plain'
|
||||
TEXT: Mimes.text
|
||||
};
|
||||
|
||||
export function applyDragImage(event: DragEvent, label: string | null, clazz: string): void {
|
||||
|
||||
+13
-14
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IMouseEvent, StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { TimeoutTimer } from 'vs/base/common/async';
|
||||
@@ -975,8 +974,8 @@ class FocusTracker extends Disposable implements IFocusTracker {
|
||||
}
|
||||
};
|
||||
|
||||
this._register(domEvent(element, EventType.FOCUS, true)(onFocus));
|
||||
this._register(domEvent(element, EventType.BLUR, true)(onBlur));
|
||||
this._register(addDisposableListener(element, EventType.FOCUS, onFocus, true));
|
||||
this._register(addDisposableListener(element, EventType.BLUR, onBlur, true));
|
||||
}
|
||||
|
||||
refreshState() {
|
||||
@@ -1480,7 +1479,7 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
|
||||
metaKey: false
|
||||
};
|
||||
|
||||
this._subscriptions.add(domEvent(window, 'keydown', true)(e => {
|
||||
this._subscriptions.add(addDisposableListener(window, 'keydown', e => {
|
||||
if (e.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
@@ -1515,9 +1514,9 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
|
||||
this._keyStatus.event = e;
|
||||
this.fire(this._keyStatus);
|
||||
}
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._subscriptions.add(domEvent(window, 'keyup', true)(e => {
|
||||
this._subscriptions.add(addDisposableListener(window, 'keyup', e => {
|
||||
if (e.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
@@ -1547,23 +1546,23 @@ export class ModifierKeyEmitter extends Emitter<IModifierKeyStatus> {
|
||||
this._keyStatus.event = e;
|
||||
this.fire(this._keyStatus);
|
||||
}
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._subscriptions.add(domEvent(document.body, 'mousedown', true)(e => {
|
||||
this._subscriptions.add(addDisposableListener(document.body, 'mousedown', () => {
|
||||
this._keyStatus.lastKeyPressed = undefined;
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._subscriptions.add(domEvent(document.body, 'mouseup', true)(e => {
|
||||
this._subscriptions.add(addDisposableListener(document.body, 'mouseup', () => {
|
||||
this._keyStatus.lastKeyPressed = undefined;
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._subscriptions.add(domEvent(document.body, 'mousemove', true)(e => {
|
||||
this._subscriptions.add(addDisposableListener(document.body, 'mousemove', e => {
|
||||
if (e.buttons) {
|
||||
this._keyStatus.lastKeyPressed = undefined;
|
||||
}
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._subscriptions.add(domEvent(window, 'blur')(e => {
|
||||
this._subscriptions.add(addDisposableListener(window, 'blur', () => {
|
||||
this.resetKeyStatus();
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -14,24 +14,7 @@ export interface IDomEvent {
|
||||
(element: EventHandler, type: string, useCapture?: boolean): BaseEvent<unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `DomEmitter` instead
|
||||
*/
|
||||
export const domEvent: IDomEvent = (element: EventHandler, type: string, useCapture?: boolean) => {
|
||||
const fn = (e: Event) => emitter.fire(e);
|
||||
const emitter = new Emitter<Event>({
|
||||
onFirstListenerAdd: () => {
|
||||
element.addEventListener(type, fn, useCapture);
|
||||
},
|
||||
onLastListenerRemove: () => {
|
||||
element.removeEventListener(type, fn, useCapture);
|
||||
}
|
||||
});
|
||||
|
||||
return emitter.event;
|
||||
};
|
||||
|
||||
export interface DOMEventMap extends HTMLElementEventMap {
|
||||
export interface DOMEventMap extends HTMLElementEventMap, DocumentEventMap {
|
||||
'-monaco-gesturetap': GestureEvent;
|
||||
'-monaco-gesturechange': GestureEvent;
|
||||
'-monaco-gesturestart': GestureEvent;
|
||||
@@ -47,6 +30,8 @@ export class DomEmitter<K extends keyof DOMEventMap> implements IDisposable {
|
||||
return this.emitter.event;
|
||||
}
|
||||
|
||||
constructor(element: Document, type: DocumentEventMap, useCapture?: boolean);
|
||||
constructor(element: EventHandler, type: K, useCapture?: boolean);
|
||||
constructor(element: EventHandler, type: K, useCapture?: boolean) {
|
||||
const fn = (e: Event) => this.emitter.fire(e as DOMEventMap[K]);
|
||||
this.emitter = new Emitter({
|
||||
|
||||
@@ -20,7 +20,7 @@ import { resolvePath } from 'vs/base/common/resources';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { renderLabelWithIcons } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
export interface MarkedOptions extends marked.MarkedOptions {
|
||||
baseUrl?: never;
|
||||
@@ -186,7 +186,9 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
}
|
||||
|
||||
if (options.actionHandler) {
|
||||
options.actionHandler.disposeables.add(Event.any<MouseEvent>(domEvent(element, 'click'), domEvent(element, 'auxclick'))(e => {
|
||||
const onClick = options.actionHandler.disposeables.add(new DomEmitter(element, 'click'));
|
||||
const onAuxClick = options.actionHandler.disposeables.add(new DomEmitter(element, 'auxclick'));
|
||||
options.actionHandler.disposeables.add(Event.any(onClick.event, onAuxClick.event)(e => {
|
||||
const mouseEvent = new StandardMouseEvent(e);
|
||||
if (!mouseEvent.leftButton && !mouseEvent.middleButton) {
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,6 @@ import 'vs/css!./dialog';
|
||||
import * as nls from 'vs/nls';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { $, hide, show, EventHelper, clearNode, isAncestor, addDisposableListener, EventType } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
@@ -220,7 +219,7 @@ export class Dialog extends Disposable {
|
||||
});
|
||||
|
||||
// Handle keyboard events gloably: Tab, Arrow-Left/Right
|
||||
this._register(domEvent(window, 'keydown', true)((e: KeyboardEvent) => {
|
||||
this._register(addDisposableListener(window, 'keydown', e => {
|
||||
const evt = new StandardKeyboardEvent(e);
|
||||
|
||||
if (evt.equals(KeyMod.Alt)) {
|
||||
@@ -321,9 +320,9 @@ export class Dialog extends Disposable {
|
||||
} else if (this.options.keyEventProcessor) {
|
||||
this.options.keyEventProcessor(evt);
|
||||
}
|
||||
}));
|
||||
}, true));
|
||||
|
||||
this._register(domEvent(window, 'keyup', true)((e: KeyboardEvent) => {
|
||||
this._register(addDisposableListener(window, 'keyup', e => {
|
||||
EventHelper.stop(e, true);
|
||||
const evt = new StandardKeyboardEvent(e);
|
||||
|
||||
@@ -333,10 +332,10 @@ export class Dialog extends Disposable {
|
||||
checkboxChecked: this.checkbox ? this.checkbox.checked : undefined
|
||||
});
|
||||
}
|
||||
}));
|
||||
}, true));
|
||||
|
||||
// Detect focus out
|
||||
this._register(domEvent(this.element, 'focusout', false)((e: FocusEvent) => {
|
||||
this._register(addDisposableListener(this.element, 'focusout', e => {
|
||||
if (!!e.relatedTarget && !!this.element) {
|
||||
if (!isAncestor(e.relatedTarget as HTMLElement, this.element)) {
|
||||
this.focusToReturn = e.relatedTarget as HTMLElement;
|
||||
@@ -347,7 +346,7 @@ export class Dialog extends Disposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}, false));
|
||||
|
||||
const spinModifierClassName = 'codicon-modifier-spin';
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
import { isFunction, isString } from 'vs/base/common/types';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { IIconLabelMarkdownString } from 'vs/base/browser/ui/iconLabel/iconLabel';
|
||||
import { IHoverDelegate, IHoverDelegateOptions, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
|
||||
import { IHoverDelegate, IHoverDelegateTarget } from 'vs/base/browser/ui/iconLabel/iconHoverDelegate';
|
||||
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
|
||||
|
||||
export function setupNativeHover(htmlElement: HTMLElement, tooltip: string | IIconLabelMarkdownString | undefined): void {
|
||||
@@ -32,79 +32,90 @@ export function setupCustomHover(hoverDelegate: IHoverDelegate, htmlElement: HTM
|
||||
|
||||
const tooltip = getTooltipForCustom(markdownTooltip);
|
||||
|
||||
let hoverOptions: IHoverDelegateOptions | undefined;
|
||||
let mouseX: number | undefined;
|
||||
let isHovering = false;
|
||||
let tokenSource: CancellationTokenSource;
|
||||
let hoverDisposable: IDisposable | undefined;
|
||||
let hoverPreparation: IDisposable | undefined;
|
||||
|
||||
const mouseOverDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_OVER, true);
|
||||
mouseOverDomEmitter.event((e: MouseEvent) => {
|
||||
if (isHovering) {
|
||||
let hoverWidget: IDisposable | undefined;
|
||||
|
||||
const mouseEnter = (e: MouseEvent) => {
|
||||
if (hoverPreparation) {
|
||||
return;
|
||||
}
|
||||
tokenSource = new CancellationTokenSource();
|
||||
function mouseLeaveOrDown(e: MouseEvent): void {
|
||||
|
||||
const tokenSource = new CancellationTokenSource();
|
||||
|
||||
const mouseLeaveOrDown = (e: MouseEvent) => {
|
||||
const isMouseDown = e.type === dom.EventType.MOUSE_DOWN;
|
||||
if (isMouseDown) {
|
||||
hoverDisposable?.dispose();
|
||||
hoverDisposable = undefined;
|
||||
hoverWidget?.dispose();
|
||||
hoverWidget = undefined;
|
||||
}
|
||||
if (isMouseDown || (<any>e).fromElement === htmlElement) {
|
||||
isHovering = false;
|
||||
hoverOptions = undefined;
|
||||
tokenSource.dispose(true);
|
||||
mouseLeaveDomEmitter.dispose();
|
||||
mouseDownDomEmitter.dispose();
|
||||
hoverPreparation?.dispose();
|
||||
hoverPreparation = undefined;
|
||||
}
|
||||
}
|
||||
const mouseLeaveDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_LEAVE, true);
|
||||
mouseLeaveDomEmitter.event(mouseLeaveOrDown);
|
||||
const mouseDownDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_DOWN, true);
|
||||
mouseDownDomEmitter.event(mouseLeaveOrDown);
|
||||
isHovering = true;
|
||||
};
|
||||
const mouseLeaveDomListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_LEAVE, mouseLeaveOrDown, true);
|
||||
const mouseDownDownListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_DOWN, mouseLeaveOrDown, true);
|
||||
|
||||
function mouseMove(e: MouseEvent): void {
|
||||
mouseX = e.x;
|
||||
const target: IHoverDelegateTarget = {
|
||||
targetElements: [htmlElement],
|
||||
dispose: () => { }
|
||||
};
|
||||
|
||||
let mouseMoveDomListener: IDisposable | undefined;
|
||||
if (hoverDelegate.placement === undefined || hoverDelegate.placement === 'mouse') {
|
||||
const mouseMove = (e: MouseEvent) => target.x = e.x + 10;
|
||||
mouseMoveDomListener = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_MOVE, mouseMove, true);
|
||||
}
|
||||
const mouseMoveDomEmitter = new DomEmitter(htmlElement, dom.EventType.MOUSE_MOVE, true);
|
||||
mouseMoveDomEmitter.event(mouseMove);
|
||||
setTimeout(async () => {
|
||||
if (isHovering && tooltip) {
|
||||
// Re-use the already computed hover options if they exist.
|
||||
if (!hoverOptions) {
|
||||
const target: IHoverDelegateTarget = {
|
||||
targetElements: [htmlElement],
|
||||
dispose: () => { }
|
||||
};
|
||||
hoverOptions = {
|
||||
text: localize('iconLabel.loading', "Loading..."),
|
||||
|
||||
const showHover = async () => {
|
||||
if (hoverPreparation) {
|
||||
|
||||
const hoverOptions = {
|
||||
text: localize('iconLabel.loading', "Loading..."),
|
||||
target,
|
||||
hoverPosition: HoverPosition.BELOW
|
||||
};
|
||||
hoverWidget?.dispose();
|
||||
hoverWidget = hoverDelegate.showHover(hoverOptions);
|
||||
|
||||
const resolvedTooltip = (await tooltip(tokenSource.token)) ?? (!isString(markdownTooltip) ? markdownTooltip.markdownNotSupportedFallback : undefined);
|
||||
|
||||
hoverWidget?.dispose();
|
||||
hoverWidget = undefined;
|
||||
|
||||
// awaiting the tooltip could take a while. Make sure we're still preparing to hover.
|
||||
if (resolvedTooltip && hoverPreparation) {
|
||||
const hoverOptions = {
|
||||
text: resolvedTooltip,
|
||||
target,
|
||||
showPointer: hoverDelegate.placement === 'element',
|
||||
hoverPosition: HoverPosition.BELOW
|
||||
};
|
||||
hoverDisposable = adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
|
||||
|
||||
const resolvedTooltip = (await tooltip(tokenSource.token)) ?? (!isString(markdownTooltip) ? markdownTooltip.markdownNotSupportedFallback : undefined);
|
||||
if (resolvedTooltip) {
|
||||
hoverOptions = {
|
||||
text: resolvedTooltip,
|
||||
target,
|
||||
showPointer: hoverDelegate.placement === 'element',
|
||||
hoverPosition: HoverPosition.BELOW
|
||||
};
|
||||
// awaiting the tooltip could take a while. Make sure we're still hovering.
|
||||
hoverDisposable = adjustXAndShowCustomHover(hoverOptions, mouseX, hoverDelegate, isHovering);
|
||||
} else if (hoverDisposable) {
|
||||
hoverDisposable.dispose();
|
||||
hoverDisposable = undefined;
|
||||
}
|
||||
hoverWidget = hoverDelegate.showHover(hoverOptions);
|
||||
}
|
||||
|
||||
}
|
||||
mouseMoveDomEmitter.dispose();
|
||||
}, hoverDelegate.delay);
|
||||
mouseMoveDomListener?.dispose();
|
||||
};
|
||||
const timeout = new RunOnceScheduler(showHover, hoverDelegate.delay);
|
||||
timeout.schedule();
|
||||
|
||||
hoverPreparation = toDisposable(() => {
|
||||
timeout.dispose();
|
||||
mouseMoveDomListener?.dispose();
|
||||
mouseDownDownListener.dispose();
|
||||
mouseLeaveDomListener.dispose();
|
||||
tokenSource.dispose(true);
|
||||
});
|
||||
};
|
||||
const mouseOverDomEmitter = dom.addDisposableListener(htmlElement, dom.EventType.MOUSE_OVER, mouseEnter, true);
|
||||
return toDisposable(() => {
|
||||
mouseOverDomEmitter.dispose();
|
||||
hoverPreparation?.dispose();
|
||||
hoverWidget?.dispose();
|
||||
});
|
||||
return mouseOverDomEmitter;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,13 +129,3 @@ function getTooltipForCustom(markdownTooltip: string | IIconLabelMarkdownString)
|
||||
return async () => markdown;
|
||||
}
|
||||
}
|
||||
|
||||
function adjustXAndShowCustomHover(hoverOptions: IHoverDelegateOptions | undefined, mouseX: number | undefined, hoverDelegate: IHoverDelegate, isHovering: boolean): IDisposable | undefined {
|
||||
if (hoverOptions && isHovering) {
|
||||
if (mouseX !== undefined && (hoverDelegate.placement === undefined || hoverDelegate.placement === 'mouse')) {
|
||||
(<IHoverDelegateTarget>hoverOptions.target).x = mouseX + 10;
|
||||
}
|
||||
return hoverDelegate.showHover(hoverOptions);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import { HistoryNavigator } from 'vs/base/common/history';
|
||||
import { IHistoryNavigationWidget } from 'vs/base/browser/history';
|
||||
import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -189,13 +189,14 @@ export class InputBox extends Widget {
|
||||
// from ScrollableElement to DOM
|
||||
this._register(this.scrollableElement.onScroll(e => this.input.scrollTop = e.scrollTop));
|
||||
|
||||
const onSelectionChange = Event.filter(domEvent(document, 'selectionchange'), () => {
|
||||
const onSelectionChange = this._register(new DomEmitter(document, 'selectionchange'));
|
||||
const onAnchoredSelectionChange = Event.filter(onSelectionChange.event, () => {
|
||||
const selection = document.getSelection();
|
||||
return selection?.anchorNode === wrapper;
|
||||
});
|
||||
|
||||
// from DOM to ScrollableElement
|
||||
this._register(onSelectionChange(this.updateScrollDimensions, this));
|
||||
this._register(onAnchoredSelectionChange(this.updateScrollDimensions, this));
|
||||
this._register(this.onDidHeightChange(this.updateScrollDimensions, this));
|
||||
} else {
|
||||
this.input.type = this.options.type || 'text';
|
||||
|
||||
@@ -7,7 +7,6 @@ import { getOrDefault } from 'vs/base/common/objects';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { ScrollEvent, ScrollbarVisibility, INewScrollDimensions, Scrollable } from 'vs/base/common/scrollable';
|
||||
import { RangeMap, shift } from './rangeMap';
|
||||
@@ -21,7 +20,8 @@ import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd'
|
||||
import { disposableTimeout, Delayer } from 'vs/base/common/async';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { IMouseWheelEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { $, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { $, addDisposableListener, animate, getContentHeight, getContentWidth, getTopLeftOffset, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
interface IItem<T> {
|
||||
readonly id: string;
|
||||
@@ -339,17 +339,16 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
container.appendChild(this.domNode);
|
||||
|
||||
this.scrollableElement.onScroll(this.onScroll, this, this.disposables);
|
||||
domEvent(this.rowsContainer, TouchEventType.Change)(e => this.onTouchChange(e as GestureEvent), this, this.disposables);
|
||||
this.disposables.add(addDisposableListener(this.rowsContainer, TouchEventType.Change, e => this.onTouchChange(e as GestureEvent)));
|
||||
|
||||
// Prevent the monaco-scrollable-element from scrolling
|
||||
// https://github.com/microsoft/vscode/issues/44181
|
||||
domEvent(this.scrollableElement.getDomNode(), 'scroll')
|
||||
(e => (e.target as HTMLElement).scrollTop = 0, null, this.disposables);
|
||||
this.disposables.add(addDisposableListener(this.scrollableElement.getDomNode(), 'scroll', e => (e.target as HTMLElement).scrollTop = 0));
|
||||
|
||||
Event.map(domEvent(this.domNode, 'dragover'), e => this.toDragEvent(e))(this.onDragOver, this, this.disposables);
|
||||
Event.map(domEvent(this.domNode, 'drop'), e => this.toDragEvent(e))(this.onDrop, this, this.disposables);
|
||||
domEvent(this.domNode, 'dragleave')(this.onDragLeave, this, this.disposables);
|
||||
domEvent(window, 'dragend')(this.onDragEnd, this, this.disposables);
|
||||
this.disposables.add(addDisposableListener(this.domNode, 'dragover', e => this.onDragOver(this.toDragEvent(e))));
|
||||
this.disposables.add(addDisposableListener(this.domNode, 'drop', e => this.onDrop(this.toDragEvent(e))));
|
||||
this.disposables.add(addDisposableListener(this.domNode, 'dragleave', _ => this.onDragLeave()));
|
||||
this.disposables.add(addDisposableListener(this.domNode, 'dragend', e => this.onDragEnd(e)));
|
||||
|
||||
this.setRowLineHeight = getOrDefault(options, o => o.setRowLineHeight, DefaultOptions.setRowLineHeight);
|
||||
this.setRowHeight = getOrDefault(options, o => o.setRowHeight, DefaultOptions.setRowHeight);
|
||||
@@ -775,8 +774,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
item.row.domNode.draggable = !!uri;
|
||||
|
||||
if (uri) {
|
||||
const onDragStart = domEvent(item.row.domNode, 'dragstart');
|
||||
item.dragStartDisposable = onDragStart(event => this.onDragStart(item.element, uri, event));
|
||||
item.dragStartDisposable = addDisposableListener(item.row.domNode, 'dragstart', event => this.onDragStart(item.element, uri, event));
|
||||
}
|
||||
|
||||
if (this.horizontalScrolling) {
|
||||
@@ -890,17 +888,17 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
// Events
|
||||
|
||||
@memoize get onMouseClick(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'click'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseDblClick(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'dblclick'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseMiddleClick(): Event<IListMouseEvent<T>> { return Event.filter(Event.map(domEvent(this.domNode, 'auxclick'), e => this.toMouseEvent(e as MouseEvent)), e => e.browserEvent.button === 1); }
|
||||
@memoize get onMouseUp(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseup'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseDown(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mousedown'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseOver(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseover'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseMove(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mousemove'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseOut(): Event<IListMouseEvent<T>> { return Event.map(domEvent(this.domNode, 'mouseout'), e => this.toMouseEvent(e)); }
|
||||
@memoize get onContextMenu(): Event<IListMouseEvent<T> | IListGestureEvent<T>> { return Event.any(Event.map(domEvent(this.domNode, 'contextmenu'), e => this.toMouseEvent(e)), Event.map(domEvent(this.domNode, TouchEventType.Contextmenu) as Event<GestureEvent>, e => this.toGestureEvent(e))); }
|
||||
@memoize get onTouchStart(): Event<IListTouchEvent<T>> { return Event.map(domEvent(this.domNode, 'touchstart'), e => this.toTouchEvent(e)); }
|
||||
@memoize get onTap(): Event<IListGestureEvent<T>> { return Event.map(domEvent(this.rowsContainer, TouchEventType.Tap), e => this.toGestureEvent(e as GestureEvent)); }
|
||||
@memoize get onMouseClick(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'click')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseDblClick(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'dblclick')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseMiddleClick(): Event<IListMouseEvent<T>> { return Event.filter(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'auxclick')).event, e => this.toMouseEvent(e as MouseEvent)), e => e.browserEvent.button === 1); }
|
||||
@memoize get onMouseUp(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseup')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseDown(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousedown')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseOver(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseover')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseMove(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mousemove')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onMouseOut(): Event<IListMouseEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'mouseout')).event, e => this.toMouseEvent(e)); }
|
||||
@memoize get onContextMenu(): Event<IListMouseEvent<T> | IListGestureEvent<T>> { return Event.any(Event.map(this.disposables.add(new DomEmitter(this.domNode, 'contextmenu')).event, e => this.toMouseEvent(e)), Event.map(this.disposables.add(new DomEmitter(this.domNode, TouchEventType.Contextmenu)).event as Event<GestureEvent>, e => this.toGestureEvent(e))); }
|
||||
@memoize get onTouchStart(): Event<IListTouchEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.domNode, 'touchstart')).event, e => this.toTouchEvent(e)); }
|
||||
@memoize get onTap(): Event<IListGestureEvent<T>> { return Event.map(this.disposables.add(new DomEmitter(this.rowsContainer, TouchEventType.Tap)).event, e => this.toGestureEvent(e as GestureEvent)); }
|
||||
|
||||
private toMouseEvent(browserEvent: MouseEvent): IListMouseEvent<T> {
|
||||
const index = this.getItemIndexFromEventTarget(browserEvent.target || null);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Gesture } from 'vs/base/browser/touch';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Event, Emitter, EventBufferer } from 'vs/base/common/event';
|
||||
import { domEvent, stopEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter, stopEvent } from 'vs/base/browser/event';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListError, IKeyboardNavigationDelegate } from './list';
|
||||
import { ListView, IListViewOptions, IListViewDragAndDrop, IListViewAccessibilityProvider, IListViewOptionsUpdate } from './listView';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
@@ -257,7 +257,7 @@ class KeyboardController<T> implements IDisposable {
|
||||
) {
|
||||
const multipleSelectionSupport = options.multipleSelectionSupport !== false;
|
||||
|
||||
const onKeyDown = Event.chain(domEvent(view.domNode, 'keydown'))
|
||||
const onKeyDown = Event.chain(this.disposables.add(new DomEmitter(view.domNode, 'keydown')).event)
|
||||
.filter(e => !isInputElement(e.target as HTMLElement))
|
||||
.map(e => new StandardKeyboardEvent(e));
|
||||
|
||||
@@ -394,7 +394,7 @@ class TypeLabelController<T> implements IDisposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const onChar = Event.chain(domEvent(this.view.domNode, 'keydown'))
|
||||
const onChar = Event.chain(this.enabledDisposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)
|
||||
.filter(e => !isInputElement(e.target as HTMLElement))
|
||||
.filter(() => this.automaticKeyboardNavigation || this.triggered)
|
||||
.map(event => new StandardKeyboardEvent(event))
|
||||
@@ -477,7 +477,7 @@ class DOMFocusController<T> implements IDisposable {
|
||||
private list: List<T>,
|
||||
private view: ListView<T>
|
||||
) {
|
||||
const onKeyDown = Event.chain(domEvent(view.domNode, 'keydown'))
|
||||
const onKeyDown = Event.chain(this.disposables.add(new DomEmitter(view.domNode, 'keydown')).event)
|
||||
.filter(e => !isInputElement(e.target as HTMLElement))
|
||||
.map(e => new StandardKeyboardEvent(e));
|
||||
|
||||
@@ -1184,14 +1184,14 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
@memoize get onContextMenu(): Event<IListContextMenuEvent<T>> {
|
||||
let didJustPressContextMenuKey = false;
|
||||
|
||||
const fromKeyDown = Event.chain(domEvent(this.view.domNode, 'keydown'))
|
||||
const fromKeyDown = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event)
|
||||
.map(e => new StandardKeyboardEvent(e))
|
||||
.filter(e => didJustPressContextMenuKey = e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
|
||||
.map(stopEvent)
|
||||
.filter(() => false)
|
||||
.event as Event<any>;
|
||||
|
||||
const fromKeyUp = Event.chain(domEvent(this.view.domNode, 'keyup'))
|
||||
const fromKeyUp = Event.chain(this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event)
|
||||
.forEach(() => didJustPressContextMenuKey = false)
|
||||
.map(e => new StandardKeyboardEvent(e))
|
||||
.filter(e => e.keyCode === KeyCode.ContextMenu || (e.shiftKey && e.keyCode === KeyCode.F10))
|
||||
@@ -1213,12 +1213,12 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
return Event.any<IListContextMenuEvent<T>>(fromKeyDown, fromKeyUp, fromMouse);
|
||||
}
|
||||
|
||||
get onKeyDown(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keydown'); }
|
||||
get onKeyUp(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keyup'); }
|
||||
get onKeyPress(): Event<KeyboardEvent> { return domEvent(this.view.domNode, 'keypress'); }
|
||||
@memoize get onKeyDown(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keydown')).event; }
|
||||
@memoize get onKeyUp(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keyup')).event; }
|
||||
@memoize get onKeyPress(): Event<KeyboardEvent> { return this.disposables.add(new DomEmitter(this.view.domNode, 'keypress')).event; }
|
||||
|
||||
readonly onDidFocus: Event<void>;
|
||||
readonly onDidBlur: Event<void>;
|
||||
@memoize get onDidFocus(): Event<void> { return Event.signal(this.disposables.add(new DomEmitter(this.view.domNode, 'focus', true)).event); }
|
||||
@memoize get onDidBlur(): Event<void> { return Event.signal(this.disposables.add(new DomEmitter(this.view.domNode, 'blur', true)).event); }
|
||||
|
||||
private readonly _onDidDispose = new Emitter<void>();
|
||||
readonly onDidDispose: Event<void> = this._onDidDispose.event;
|
||||
@@ -1277,9 +1277,6 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
||||
this.disposables.add(this.view);
|
||||
this.disposables.add(this._onDidDispose);
|
||||
|
||||
this.onDidFocus = Event.map(domEvent(this.view.domNode, 'focus', true), () => null!);
|
||||
this.onDidBlur = Event.map(domEvent(this.view.domNode, 'blur', true), () => null!);
|
||||
|
||||
this.disposables.add(new DOMFocusController(this, this.view));
|
||||
|
||||
if (typeof _options.keyboardSupport !== 'boolean' || _options.keyboardSupport) {
|
||||
|
||||
@@ -14,7 +14,7 @@ import * as arrays from 'vs/base/common/arrays';
|
||||
import { IContextViewProvider, AnchorPosition } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
|
||||
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
@@ -736,7 +736,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
}
|
||||
|
||||
// SetUp list keyboard controller - control navigation, disabled items, focus
|
||||
const onSelectDropDownKeyDown = Event.chain(domEvent(this.selectDropDownListContainer, 'keydown'))
|
||||
const onKeyDown = this._register(new DomEmitter(this.selectDropDownListContainer, 'keydown'));
|
||||
const onSelectDropDownKeyDown = Event.chain(onKeyDown.event)
|
||||
.filter(() => this.selectList.length > 0)
|
||||
.map(e => new StandardKeyboardEvent(e));
|
||||
|
||||
@@ -752,7 +753,8 @@ export class SelectBoxList extends Disposable implements ISelectBoxDelegate, ILi
|
||||
|
||||
// SetUp list mouse controller - control navigation, disabled items, focus
|
||||
|
||||
this._register(Event.chain(domEvent(this.selectList.getHTMLElement(), 'mouseup'))
|
||||
const onMouseUp = this._register(new DomEmitter(this.selectList.getHTMLElement(), 'mouseup'));
|
||||
this._register(Event.chain(onMouseUp.event)
|
||||
.filter(() => this.selectList.length > 0)
|
||||
.on(e => this.onMouseUp(e), this));
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@
|
||||
import 'vs/css!./paneview';
|
||||
import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { $, append, trackFocus, EventHelper, clearNode } from 'vs/base/browser/dom';
|
||||
import { $, append, trackFocus, EventHelper, clearNode, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { SplitView, IView } from './splitview';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
@@ -17,6 +16,7 @@ import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
import { localize } from 'vs/nls';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
export interface IPaneOptions {
|
||||
minimumBodySize?: number;
|
||||
@@ -220,8 +220,8 @@ export abstract class Pane extends Disposable implements IView {
|
||||
|
||||
this.updateHeader();
|
||||
|
||||
|
||||
const onHeaderKeyDown = Event.chain(domEvent(this.header, 'keydown'))
|
||||
const onKeyDown = this._register(new DomEmitter(this.header, 'keydown'));
|
||||
const onHeaderKeyDown = Event.chain(onKeyDown.event)
|
||||
.map(e => new StandardKeyboardEvent(e));
|
||||
|
||||
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.Enter || e.keyCode === KeyCode.Space)
|
||||
@@ -233,12 +233,11 @@ export abstract class Pane extends Disposable implements IView {
|
||||
this._register(onHeaderKeyDown.filter(e => e.keyCode === KeyCode.RightArrow)
|
||||
.event(() => this.setExpanded(true), null));
|
||||
|
||||
this._register(domEvent(this.header, 'click')
|
||||
(e => {
|
||||
if (!e.defaultPrevented) {
|
||||
this.setExpanded(!this.isExpanded());
|
||||
}
|
||||
}, null));
|
||||
this._register(addDisposableListener(this.header, 'click', e => {
|
||||
if (!e.defaultPrevented) {
|
||||
this.setExpanded(!this.isExpanded());
|
||||
}
|
||||
}));
|
||||
|
||||
this.body = append(this.element, $('.pane-body'));
|
||||
this.renderBody(this.body);
|
||||
@@ -308,11 +307,11 @@ class PaneDraggable extends Disposable {
|
||||
super();
|
||||
|
||||
pane.draggableElement.draggable = true;
|
||||
this._register(domEvent(pane.draggableElement, 'dragstart')(this.onDragStart, this));
|
||||
this._register(domEvent(pane.dropTargetElement, 'dragenter')(this.onDragEnter, this));
|
||||
this._register(domEvent(pane.dropTargetElement, 'dragleave')(this.onDragLeave, this));
|
||||
this._register(domEvent(pane.dropTargetElement, 'dragend')(this.onDragEnd, this));
|
||||
this._register(domEvent(pane.dropTargetElement, 'drop')(this.onDrop, this));
|
||||
this._register(addDisposableListener(pane.draggableElement, 'dragstart', e => this.onDragStart(e)));
|
||||
this._register(addDisposableListener(pane.dropTargetElement, 'dragenter', e => this.onDragEnter(e)));
|
||||
this._register(addDisposableListener(pane.dropTargetElement, 'dragleave', e => this.onDragLeave(e)));
|
||||
this._register(addDisposableListener(pane.dropTargetElement, 'dragend', e => this.onDragEnd(e)));
|
||||
this._register(addDisposableListener(pane.dropTargetElement, 'drop', e => this.onDrop(e)));
|
||||
}
|
||||
|
||||
private onDragStart(e: DragEvent): void {
|
||||
|
||||
@@ -11,8 +11,7 @@ import { clamp } from 'vs/base/common/numbers';
|
||||
import { range, pushToStart, pushToEnd } from 'vs/base/common/arrays';
|
||||
import { Sash, Orientation, ISashEvent as IBaseSashEvent, SashState } from 'vs/base/browser/ui/sash/sash';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { $, append, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { $, addDisposableListener, append, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
||||
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
|
||||
export { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
@@ -488,8 +487,8 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
||||
|
||||
// This way, we can press Alt while we resize a sash, macOS style!
|
||||
const disposable = combinedDisposable(
|
||||
domEvent(document.body, 'keydown')(e => resetSashDragState(this.sashDragState!.current, e.altKey)),
|
||||
domEvent(document.body, 'keyup')(() => resetSashDragState(this.sashDragState!.current, false))
|
||||
addDisposableListener(document.body, 'keydown', e => resetSashDragState(this.sashDragState!.current, e.altKey)),
|
||||
addDisposableListener(document.body, 'keyup', () => resetSashDragState(this.sashDragState!.current, false))
|
||||
);
|
||||
|
||||
const resetSashDragState = (start: number, alt: boolean) => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'vs/css!./media/tree';
|
||||
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate, isInputElement, isMonacoEditor } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom';
|
||||
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
@@ -16,7 +16,7 @@ import { ISpliceable } from 'vs/base/common/sequence';
|
||||
import { IDragAndDropData, StaticDND, DragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { range, equals, distinctES6, firstOrDefault } from 'vs/base/common/arrays';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters';
|
||||
import { getVisibleState, isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -648,7 +648,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
) {
|
||||
this.domNode = $(`.monaco-list-type-filter.${this.positionClassName}`);
|
||||
this.domNode.draggable = true;
|
||||
domEvent(this.domNode, 'dragstart')(this.onDragStart, this, this.disposables);
|
||||
this.disposables.add(addDisposableListener(this.domNode, 'dragstart', () => this.onDragStart()));
|
||||
|
||||
this.messageDomNode = append(view.getHTMLElement(), $(`.monaco-list-type-filter-message`));
|
||||
|
||||
@@ -661,7 +661,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
this.filterOnTypeDomNode.checked = this._filterOnType;
|
||||
this.filterOnTypeDomNode.tabIndex = -1;
|
||||
this.updateFilterOnTypeTitleAndIcon();
|
||||
domEvent(this.filterOnTypeDomNode, 'input')(this.onDidChangeFilterOnType, this, this.disposables);
|
||||
this.disposables.add(addDisposableListener(this.filterOnTypeDomNode, 'input', () => this.onDidChangeFilterOnType()));
|
||||
|
||||
this.clearDomNode = append(controls, $<HTMLInputElement>('button.clear' + treeFilterClearIcon.cssSelector));
|
||||
this.clearDomNode.tabIndex = -1;
|
||||
@@ -711,7 +711,8 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
return;
|
||||
}
|
||||
|
||||
const onKeyDown = Event.chain(domEvent(this.view.getHTMLElement(), 'keydown'))
|
||||
const onRawKeyDown = this.enabledDisposables.add(new DomEmitter(this.view.getHTMLElement(), 'keydown'));
|
||||
const onKeyDown = Event.chain(onRawKeyDown.event)
|
||||
.filter(e => !isInputElement(e.target as HTMLElement) || e.target === this.filterOnTypeDomNode)
|
||||
.filter(e => e.key !== 'Dead' && !/^Media/.test(e.key))
|
||||
.map(e => new StandardKeyboardEvent(e))
|
||||
@@ -721,9 +722,9 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
.forEach(e => { e.stopPropagation(); e.preventDefault(); })
|
||||
.event;
|
||||
|
||||
const onClear = domEvent(this.clearDomNode, 'click');
|
||||
const onClearClick = this.enabledDisposables.add(new DomEmitter(this.clearDomNode, 'click'));
|
||||
|
||||
Event.chain(Event.any<MouseEvent | StandardKeyboardEvent>(onKeyDown, onClear))
|
||||
Event.chain(Event.any<MouseEvent | StandardKeyboardEvent>(onKeyDown, onClearClick.event))
|
||||
.event(this.onEventOrInput, this, this.enabledDisposables);
|
||||
|
||||
this.filter.pattern = '';
|
||||
@@ -849,8 +850,8 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
||||
this.domNode.classList.add('dragging');
|
||||
disposables.add(toDisposable(() => this.domNode.classList.remove('dragging')));
|
||||
|
||||
domEvent(document, 'dragover')(onDragOver, null, disposables);
|
||||
domEvent(this.domNode, 'dragend')(onDragEnd, null, disposables);
|
||||
disposables.add(addDisposableListener(document, 'dragover', e => onDragOver(e)));
|
||||
disposables.add(addDisposableListener(this.domNode, 'dragend', () => onDragEnd()));
|
||||
|
||||
StaticDND.CurrentDragAndDropData = new DragAndDropData('vscode-ui');
|
||||
disposables.add(toDisposable(() => StaticDND.CurrentDragAndDropData = undefined));
|
||||
|
||||
@@ -298,7 +298,7 @@ export class Delayer<T> implements IDisposable {
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.cancelTimeout();
|
||||
this.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,12 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DataUri } from 'vs/base/common/resources';
|
||||
|
||||
export const MIME_TEXT = 'text/plain';
|
||||
export const MIME_BINARY = 'application/octet-stream';
|
||||
export const MIME_UNKNOWN = 'application/unknown';
|
||||
export namespace Mimes {
|
||||
export const text = 'text/plain';
|
||||
export const binary = 'application/octet-stream';
|
||||
export const unknown = 'application/unknown';
|
||||
export const markdown = 'text/markdown';
|
||||
}
|
||||
|
||||
export interface ITextMimeAssociation {
|
||||
readonly id: string;
|
||||
@@ -125,7 +128,7 @@ export function guessMimeTypes(resource: URI | null, firstLine?: string): string
|
||||
}
|
||||
|
||||
if (!path) {
|
||||
return [MIME_UNKNOWN];
|
||||
return [Mimes.unknown];
|
||||
}
|
||||
|
||||
path = path.toLowerCase();
|
||||
@@ -135,24 +138,24 @@ export function guessMimeTypes(resource: URI | null, firstLine?: string): string
|
||||
// 1.) User configured mappings have highest priority
|
||||
const configuredMime = guessMimeTypeByPath(path, filename, userRegisteredAssociations);
|
||||
if (configuredMime) {
|
||||
return [configuredMime, MIME_TEXT];
|
||||
return [configuredMime, Mimes.text];
|
||||
}
|
||||
|
||||
// 2.) Registered mappings have middle priority
|
||||
const registeredMime = guessMimeTypeByPath(path, filename, nonUserRegisteredAssociations);
|
||||
if (registeredMime) {
|
||||
return [registeredMime, MIME_TEXT];
|
||||
return [registeredMime, Mimes.text];
|
||||
}
|
||||
|
||||
// 3.) Firstline has lowest priority
|
||||
if (firstLine) {
|
||||
const firstlineMime = guessMimeTypeByFirstline(firstLine);
|
||||
if (firstlineMime) {
|
||||
return [firstlineMime, MIME_TEXT];
|
||||
return [firstlineMime, Mimes.text];
|
||||
}
|
||||
}
|
||||
|
||||
return [MIME_UNKNOWN];
|
||||
return [Mimes.unknown];
|
||||
}
|
||||
|
||||
function guessMimeTypeByPath(path: string, filename: string, associations: ITextMimeAssociationItem[]): string | null {
|
||||
@@ -240,7 +243,7 @@ export function isUnspecific(mime: string[] | string): boolean {
|
||||
}
|
||||
|
||||
if (typeof mime === 'string') {
|
||||
return mime === MIME_BINARY || mime === MIME_TEXT || mime === MIME_UNKNOWN;
|
||||
return mime === Mimes.binary || mime === Mimes.text || mime === Mimes.unknown;
|
||||
}
|
||||
|
||||
return mime.length === 1 && isUnspecific(mime[0]);
|
||||
|
||||
@@ -10,9 +10,54 @@ import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as process from 'vs/base/common/process';
|
||||
|
||||
export const enum SocketCloseEventType {
|
||||
NodeSocketCloseEvent = 0,
|
||||
WebSocketCloseEvent = 1
|
||||
}
|
||||
|
||||
export interface NodeSocketCloseEvent {
|
||||
/**
|
||||
* The type of the event
|
||||
*/
|
||||
readonly type: SocketCloseEventType.NodeSocketCloseEvent;
|
||||
/**
|
||||
* `true` if the socket had a transmission error.
|
||||
*/
|
||||
readonly hadError: boolean;
|
||||
/**
|
||||
* Underlying error.
|
||||
*/
|
||||
readonly error: Error | undefined
|
||||
}
|
||||
|
||||
export interface WebSocketCloseEvent {
|
||||
/**
|
||||
* The type of the event
|
||||
*/
|
||||
readonly type: SocketCloseEventType.WebSocketCloseEvent;
|
||||
/**
|
||||
* Returns the WebSocket connection close code provided by the server.
|
||||
*/
|
||||
readonly code: number;
|
||||
/**
|
||||
* Returns the WebSocket connection close reason provided by the server.
|
||||
*/
|
||||
readonly reason: string;
|
||||
/**
|
||||
* Returns true if the connection closed cleanly; false otherwise.
|
||||
*/
|
||||
readonly wasClean: boolean;
|
||||
/**
|
||||
* Underlying event.
|
||||
*/
|
||||
readonly event: any | undefined;
|
||||
}
|
||||
|
||||
export type SocketCloseEvent = NodeSocketCloseEvent | WebSocketCloseEvent | undefined;
|
||||
|
||||
export interface ISocket extends IDisposable {
|
||||
onData(listener: (e: VSBuffer) => void): IDisposable;
|
||||
onClose(listener: () => void): IDisposable;
|
||||
onClose(listener: (e: SocketCloseEvent) => void): IDisposable;
|
||||
onEnd(listener: () => void): IDisposable;
|
||||
write(buffer: VSBuffer): void;
|
||||
end(): void;
|
||||
@@ -624,8 +669,8 @@ export class PersistentProtocol implements IMessagePassingProtocol {
|
||||
private readonly _onDidDispose = new BufferedEmitter<void>();
|
||||
readonly onDidDispose: Event<void> = this._onDidDispose.event;
|
||||
|
||||
private readonly _onSocketClose = new BufferedEmitter<void>();
|
||||
readonly onSocketClose: Event<void> = this._onSocketClose.event;
|
||||
private readonly _onSocketClose = new BufferedEmitter<SocketCloseEvent>();
|
||||
readonly onSocketClose: Event<SocketCloseEvent> = this._onSocketClose.event;
|
||||
|
||||
private readonly _onSocketTimeout = new BufferedEmitter<void>();
|
||||
readonly onSocketTimeout: Event<void> = this._onSocketTimeout.event;
|
||||
@@ -658,7 +703,7 @@ export class PersistentProtocol implements IMessagePassingProtocol {
|
||||
this._socketReader = new ProtocolReader(this._socket);
|
||||
this._socketDisposables.push(this._socketReader);
|
||||
this._socketDisposables.push(this._socketReader.onMessage(msg => this._receiveMessage(msg)));
|
||||
this._socketDisposables.push(this._socket.onClose(() => this._onSocketClose.fire()));
|
||||
this._socketDisposables.push(this._socket.onClose((e) => this._onSocketClose.fire(e)));
|
||||
if (initialChunk) {
|
||||
this._socketReader.acceptChunk(initialChunk);
|
||||
}
|
||||
@@ -768,7 +813,7 @@ export class PersistentProtocol implements IMessagePassingProtocol {
|
||||
this._socketReader = new ProtocolReader(this._socket);
|
||||
this._socketDisposables.push(this._socketReader);
|
||||
this._socketDisposables.push(this._socketReader.onMessage(msg => this._receiveMessage(msg)));
|
||||
this._socketDisposables.push(this._socket.onClose(() => this._onSocketClose.fire()));
|
||||
this._socketDisposables.push(this._socket.onClose((e) => this._onSocketClose.fire(e)));
|
||||
this._socketReader.acceptChunk(initialDataChunk);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { tmpdir } from 'os';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { ISocket, Protocol, Client, ChunkStream } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { ISocket, Protocol, Client, ChunkStream, SocketCloseEvent, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Platform, platform } from 'vs/base/common/platform';
|
||||
|
||||
@@ -54,10 +54,17 @@ export class NodeSocket implements ISocket {
|
||||
};
|
||||
}
|
||||
|
||||
public onClose(listener: () => void): IDisposable {
|
||||
this.socket.on('close', listener);
|
||||
public onClose(listener: (e: SocketCloseEvent) => void): IDisposable {
|
||||
const adapter = (hadError: boolean) => {
|
||||
listener({
|
||||
type: SocketCloseEventType.NodeSocketCloseEvent,
|
||||
hadError: hadError,
|
||||
error: undefined
|
||||
});
|
||||
};
|
||||
this.socket.on('close', adapter);
|
||||
return {
|
||||
dispose: () => this.socket.off('close', listener)
|
||||
dispose: () => this.socket.off('close', adapter)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,7 +174,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
private readonly _pendingDeflateData: Buffer[] = [];
|
||||
private readonly _incomingData: ChunkStream;
|
||||
private readonly _onData = this._register(new Emitter<VSBuffer>());
|
||||
private readonly _onClose = this._register(new Emitter<void>());
|
||||
private readonly _onClose = this._register(new Emitter<SocketCloseEvent>());
|
||||
private _isEnded: boolean = false;
|
||||
|
||||
private readonly _state = {
|
||||
@@ -232,7 +239,11 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
// zlib errors are fatal, since we have no idea how to recover
|
||||
console.error(err);
|
||||
onUnexpectedError(err);
|
||||
this._onClose.fire();
|
||||
this._onClose.fire({
|
||||
type: SocketCloseEventType.NodeSocketCloseEvent,
|
||||
hadError: true,
|
||||
error: err
|
||||
});
|
||||
});
|
||||
this._zlibInflate.on('data', (data: Buffer) => {
|
||||
this._pendingInflateData.push(data);
|
||||
@@ -251,7 +262,11 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
// zlib errors are fatal, since we have no idea how to recover
|
||||
console.error(err);
|
||||
onUnexpectedError(err);
|
||||
this._onClose.fire();
|
||||
this._onClose.fire({
|
||||
type: SocketCloseEventType.NodeSocketCloseEvent,
|
||||
hadError: true,
|
||||
error: err
|
||||
});
|
||||
});
|
||||
this._zlibDeflate.on('data', (data: Buffer) => {
|
||||
this._pendingDeflateData.push(data);
|
||||
@@ -263,7 +278,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
this._zlibDeflateFlushWaitingCount = 0;
|
||||
this._incomingData = new ChunkStream();
|
||||
this._register(this.socket.onData(data => this._acceptChunk(data)));
|
||||
this._register(this.socket.onClose(() => this._onClose.fire()));
|
||||
this._register(this.socket.onClose((e) => this._onClose.fire(e)));
|
||||
}
|
||||
|
||||
public override dispose(): void {
|
||||
@@ -282,7 +297,7 @@ export class WebSocketNodeSocket extends Disposable implements ISocket {
|
||||
return this._onData.event(listener);
|
||||
}
|
||||
|
||||
public onClose(listener: () => void): IDisposable {
|
||||
public onClose(listener: (e: SocketCloseEvent) => void): IDisposable {
|
||||
return this._onClose.event(listener);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -161,7 +161,7 @@ suite('Decorators', () => {
|
||||
|
||||
clock.tick(200);
|
||||
assert.deepStrictEqual(spy.args, [[1], [5]]);
|
||||
spy.reset();
|
||||
spy.resetHistory();
|
||||
|
||||
t.report(4);
|
||||
t.report(5);
|
||||
|
||||
@@ -11,6 +11,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ITextAreaWrapper, ITypeData, TextAreaState, _debugComposition } from 'vs/editor/browser/controller/textAreaState';
|
||||
@@ -653,7 +654,7 @@ class ClipboardEventUtils {
|
||||
if (e.clipboardData) {
|
||||
e.preventDefault();
|
||||
|
||||
const text = e.clipboardData.getData('text/plain');
|
||||
const text = e.clipboardData.getData(Mimes.text);
|
||||
let metadata: ClipboardStoredMetadata | null = null;
|
||||
const rawmetadata = e.clipboardData.getData('vscode-editor-data');
|
||||
if (typeof rawmetadata === 'string') {
|
||||
@@ -681,7 +682,7 @@ class ClipboardEventUtils {
|
||||
|
||||
public static setTextData(e: ClipboardEvent, text: string, html: string | null | undefined, metadata: ClipboardStoredMetadata): void {
|
||||
if (e.clipboardData) {
|
||||
e.clipboardData.setData('text/plain', text);
|
||||
e.clipboardData.setData(Mimes.text, text);
|
||||
if (typeof html === 'string') {
|
||||
e.clipboardData.setData('text/html', html);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageCo
|
||||
import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
// Define extension point ids
|
||||
export const Extensions = {
|
||||
@@ -65,7 +66,7 @@ ModesRegistry.registerLanguage({
|
||||
id: PLAINTEXT_MODE_ID,
|
||||
extensions: [PLAINTEXT_EXTENSION],
|
||||
aliases: [nls.localize('plainText.alias', "Plain Text"), 'text'],
|
||||
mimetypes: ['text/plain']
|
||||
mimetypes: [Mimes.text]
|
||||
});
|
||||
LanguageConfigurationRegistry.register(PLAINTEXT_LANGUAGE_IDENTIFIER, {
|
||||
brackets: [
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { domEvent, stop } from 'vs/base/browser/event';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
@@ -90,11 +89,15 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget {
|
||||
const overloads = dom.append(controls, $('.overloads'));
|
||||
const next = dom.append(controls, $('.button' + ThemeIcon.asCSSSelector(parameterHintsNextIcon)));
|
||||
|
||||
const onPreviousClick = stop(domEvent(previous, 'click'));
|
||||
this._register(onPreviousClick(this.previous, this));
|
||||
this._register(dom.addDisposableListener(previous, 'click', e => {
|
||||
dom.EventHelper.stop(e);
|
||||
this.previous();
|
||||
}));
|
||||
|
||||
const onNextClick = stop(domEvent(next, 'click'));
|
||||
this._register(onNextClick(this.next, this));
|
||||
this._register(dom.addDisposableListener(next, 'click', e => {
|
||||
dom.EventHelper.stop(e);
|
||||
this.next();
|
||||
}));
|
||||
|
||||
const body = $('.body');
|
||||
const scrollbar = new DomScrollableElement(body, {});
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
/* See https://github.com/microsoft/monaco-editor/issues/2168#issuecomment-780078600 */
|
||||
.monaco-aria-container {
|
||||
position: absolute !important;
|
||||
top: 0; /* avoid being placed underneath a sibling element */
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
margin: -1px;
|
||||
|
||||
@@ -35,6 +35,7 @@ import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ILanguageSelection, IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { StandaloneCodeEditorServiceImpl } from 'vs/editor/standalone/browser/standaloneCodeServiceImpl';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
/**
|
||||
* Description of an action contribution
|
||||
@@ -425,7 +426,7 @@ export class StandaloneEditor extends StandaloneCodeEditor implements IStandalon
|
||||
|
||||
let model: ITextModel | null;
|
||||
if (typeof _model === 'undefined') {
|
||||
model = createTextModel(modelService, modeService, options.value || '', options.language || 'text/plain', undefined);
|
||||
model = createTextModel(modelService, modeService, options.value || '', options.language || Mimes.text, undefined);
|
||||
this._ownsModel = true;
|
||||
} else {
|
||||
model = _model;
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./menuEntryActionViewItem';
|
||||
import { asCSSUrl, ModifierKeyEmitter } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { addDisposableListener, asCSSUrl, ModifierKeyEmitter } from 'vs/base/browser/dom';
|
||||
import { IAction, Separator, SubmenuAction } from 'vs/base/common/actions';
|
||||
import { IDisposable, toDisposable, MutableDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -177,12 +176,12 @@ export class MenuEntryActionViewItem extends ActionViewItem {
|
||||
}));
|
||||
}
|
||||
|
||||
this._register(domEvent(container, 'mouseleave')(_ => {
|
||||
this._register(addDisposableListener(container, 'mouseleave', _ => {
|
||||
mouseOver = false;
|
||||
updateAltState();
|
||||
}));
|
||||
|
||||
this._register(domEvent(container, 'mouseenter')(e => {
|
||||
this._register(addDisposableListener(container, 'mouseenter', _ => {
|
||||
mouseOver = true;
|
||||
updateAltState();
|
||||
}));
|
||||
|
||||
@@ -14,9 +14,8 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IContextMenuDelegate } from 'vs/base/browser/contextmenu';
|
||||
import { EventType, $, isHTMLElement } from 'vs/base/browser/dom';
|
||||
import { EventType, $, isHTMLElement, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { attachMenuStyler } from 'vs/platform/theme/common/styler';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
|
||||
@@ -75,7 +74,9 @@ export class ContextMenuHandler {
|
||||
this.block.style.width = '100%';
|
||||
this.block.style.height = '100%';
|
||||
this.block.style.zIndex = '-1';
|
||||
domEvent(this.block, EventType.MOUSE_DOWN)((e: MouseEvent) => e.stopPropagation());
|
||||
|
||||
// TODO@Steven: this is never getting disposed
|
||||
addDisposableListener(this.block, EventType.MOUSE_DOWN, e => e.stopPropagation());
|
||||
}
|
||||
|
||||
const menuDisposables = new DisposableStore();
|
||||
@@ -94,8 +95,8 @@ export class ContextMenuHandler {
|
||||
|
||||
menu.onDidCancel(() => this.contextViewService.hideContextView(true), null, menuDisposables);
|
||||
menu.onDidBlur(() => this.contextViewService.hideContextView(true), null, menuDisposables);
|
||||
domEvent(window, EventType.BLUR)(() => { this.contextViewService.hideContextView(true); }, null, menuDisposables);
|
||||
domEvent(window, EventType.MOUSE_DOWN)((e: MouseEvent) => {
|
||||
menuDisposables.add(addDisposableListener(window, EventType.BLUR, () => this.contextViewService.hideContextView(true)));
|
||||
menuDisposables.add(addDisposableListener(window, EventType.MOUSE_DOWN, (e: MouseEvent) => {
|
||||
if (e.defaultPrevented) {
|
||||
return;
|
||||
}
|
||||
@@ -117,7 +118,7 @@ export class ContextMenuHandler {
|
||||
}
|
||||
|
||||
this.contextViewService.hideContextView(true);
|
||||
}, null, menuDisposables);
|
||||
}));
|
||||
|
||||
return combinedDisposable(menuDisposables, menu);
|
||||
},
|
||||
|
||||
@@ -60,6 +60,7 @@ export interface NativeParsedArgs {
|
||||
'enable-proposed-api'?: string[]; // undefined or array of 1 or more
|
||||
'open-url'?: boolean;
|
||||
'skip-release-notes'?: boolean;
|
||||
'skip-welcome'?: boolean;
|
||||
'disable-telemetry'?: boolean;
|
||||
'export-default-configuration'?: string;
|
||||
'install-source'?: string;
|
||||
|
||||
@@ -94,6 +94,7 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
||||
'driver': { type: 'string' },
|
||||
'logExtensionHostCommunication': { type: 'boolean' },
|
||||
'skip-release-notes': { type: 'boolean' },
|
||||
'skip-welcome': { type: 'boolean' },
|
||||
'disable-telemetry': { type: 'boolean' },
|
||||
'disable-updates': { type: 'boolean' },
|
||||
'disable-keytar': { type: 'boolean' },
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { $, EventHelper, EventLike } from 'vs/base/browser/dom';
|
||||
import { DomEmitter, domEvent } from 'vs/base/browser/event';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
@@ -67,7 +67,8 @@ export class Link extends Disposable {
|
||||
}, link.label);
|
||||
|
||||
const onClickEmitter = this._register(new DomEmitter(this.el, 'click'));
|
||||
const onEnterPress = Event.chain(domEvent(this.el, 'keypress'))
|
||||
const onKeyPress = this._register(new DomEmitter(this.el, 'keypress'));
|
||||
const onEnterPress = Event.chain(onKeyPress.event)
|
||||
.map(e => new StandardKeyboardEvent(e))
|
||||
.filter(e => e.keyCode === KeyCode.Enter)
|
||||
.event;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ISocketFactory, IConnectCallback } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import { ISocket } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { ISocket, SocketCloseEvent, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
@@ -16,10 +16,29 @@ export interface IWebSocketFactory {
|
||||
create(url: string): IWebSocket;
|
||||
}
|
||||
|
||||
export interface IWebSocketCloseEvent {
|
||||
/**
|
||||
* Returns the WebSocket connection close code provided by the server.
|
||||
*/
|
||||
readonly code: number;
|
||||
/**
|
||||
* Returns the WebSocket connection close reason provided by the server.
|
||||
*/
|
||||
readonly reason: string;
|
||||
/**
|
||||
* Returns true if the connection closed cleanly; false otherwise.
|
||||
*/
|
||||
readonly wasClean: boolean;
|
||||
/**
|
||||
* Underlying event.
|
||||
*/
|
||||
readonly event: any | undefined;
|
||||
}
|
||||
|
||||
export interface IWebSocket {
|
||||
readonly onData: Event<ArrayBuffer>;
|
||||
readonly onOpen: Event<void>;
|
||||
readonly onClose: Event<void>;
|
||||
readonly onClose: Event<IWebSocketCloseEvent | void>;
|
||||
readonly onError: Event<any>;
|
||||
|
||||
send(data: ArrayBuffer | ArrayBufferView): void;
|
||||
@@ -33,7 +52,7 @@ class BrowserWebSocket extends Disposable implements IWebSocket {
|
||||
|
||||
public readonly onOpen: Event<void>;
|
||||
|
||||
private readonly _onClose = this._register(new Emitter<void>());
|
||||
private readonly _onClose = this._register(new Emitter<IWebSocketCloseEvent>());
|
||||
public readonly onClose = this._onClose.event;
|
||||
|
||||
private readonly _onError = this._register(new Emitter<any>());
|
||||
@@ -135,7 +154,7 @@ class BrowserWebSocket extends Disposable implements IWebSocket {
|
||||
}
|
||||
}
|
||||
|
||||
this._onClose.fire();
|
||||
this._onClose.fire({ code: e.code, reason: e.reason, wasClean: e.wasClean, event: e });
|
||||
}));
|
||||
|
||||
this._register(dom.addDisposableListener(this._socket, 'error', sendErrorSoon));
|
||||
@@ -178,8 +197,21 @@ class BrowserSocket implements ISocket {
|
||||
return this.socket.onData((data) => listener(VSBuffer.wrap(new Uint8Array(data))));
|
||||
}
|
||||
|
||||
public onClose(listener: () => void): IDisposable {
|
||||
return this.socket.onClose(listener);
|
||||
public onClose(listener: (e: SocketCloseEvent) => void): IDisposable {
|
||||
const adapter = (e: IWebSocketCloseEvent | void) => {
|
||||
if (typeof e === 'undefined') {
|
||||
listener(e);
|
||||
} else {
|
||||
listener({
|
||||
type: SocketCloseEventType.WebSocketCloseEvent,
|
||||
code: e.code,
|
||||
reason: e.reason,
|
||||
wasClean: e.wasClean,
|
||||
event: e.event
|
||||
});
|
||||
}
|
||||
};
|
||||
return this.socket.onClose(adapter);
|
||||
}
|
||||
|
||||
public onEnd(listener: () => void): IDisposable {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Client, PersistentProtocol, ISocket, ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { Client, PersistentProtocol, ISocket, ProtocolConstants, SocketCloseEventType } from 'vs/base/parts/ipc/common/ipc.net';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { RemoteAgentConnectionContext } from 'vs/platform/remote/common/remoteAgentEnvironment';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
@@ -532,8 +532,28 @@ abstract class PersistentConnection extends Disposable {
|
||||
|
||||
this._onDidStateChange.fire(new ConnectionGainEvent(this.reconnectionToken, 0, 0));
|
||||
|
||||
this._register(protocol.onSocketClose(() => this._beginReconnecting()));
|
||||
this._register(protocol.onSocketTimeout(() => this._beginReconnecting()));
|
||||
this._register(protocol.onSocketClose((e) => {
|
||||
const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
|
||||
if (!e) {
|
||||
this._options.logService.info(`${logPrefix} received socket close event.`);
|
||||
} else if (e.type === SocketCloseEventType.NodeSocketCloseEvent) {
|
||||
this._options.logService.info(`${logPrefix} received socket close event (hadError: ${e.hadError}).`);
|
||||
if (e.error) {
|
||||
this._options.logService.error(e.error);
|
||||
}
|
||||
} else {
|
||||
this._options.logService.info(`${logPrefix} received socket close event (wasClean: ${e.wasClean}, code: ${e.code}, reason: ${e.reason}).`);
|
||||
if (e.event) {
|
||||
this._options.logService.error(e.event);
|
||||
}
|
||||
}
|
||||
this._beginReconnecting();
|
||||
}));
|
||||
this._register(protocol.onSocketTimeout(() => {
|
||||
const logPrefix = commonLogPrefix(this._connectionType, this.reconnectionToken, true);
|
||||
this._options.logService.trace(`${logPrefix} received socket timeout event.`);
|
||||
this._beginReconnecting();
|
||||
}));
|
||||
|
||||
PersistentConnection._instances.push(this);
|
||||
|
||||
|
||||
@@ -9,10 +9,13 @@ import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
|
||||
import { NullAppender, ITelemetryAppender } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import * as Errors from 'vs/base/common/errors';
|
||||
import * as sinon from 'sinon';
|
||||
import * as sinonTest from 'sinon-test';
|
||||
import { ITelemetryData } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
|
||||
const sinonTestFn = sinonTest(sinon);
|
||||
|
||||
class TestTelemetryAppender implements ITelemetryAppender {
|
||||
|
||||
public events: any[];
|
||||
@@ -85,7 +88,7 @@ class ErrorTestingSettings {
|
||||
|
||||
suite('TelemetryService', () => {
|
||||
|
||||
test('Disposing', sinon.test(function () {
|
||||
test('Disposing', sinonTestFn(function () {
|
||||
let testAppender = new TestTelemetryAppender();
|
||||
let service = new TelemetryService({ appender: testAppender }, undefined!);
|
||||
|
||||
@@ -98,7 +101,7 @@ suite('TelemetryService', () => {
|
||||
}));
|
||||
|
||||
// event reporting
|
||||
test('Simple event', sinon.test(function () {
|
||||
test('Simple event', sinonTestFn(function () {
|
||||
let testAppender = new TestTelemetryAppender();
|
||||
let service = new TelemetryService({ appender: testAppender }, undefined!);
|
||||
|
||||
@@ -111,7 +114,7 @@ suite('TelemetryService', () => {
|
||||
});
|
||||
}));
|
||||
|
||||
test('Event with data', sinon.test(function () {
|
||||
test('Event with data', sinonTestFn(function () {
|
||||
let testAppender = new TestTelemetryAppender();
|
||||
let service = new TelemetryService({ appender: testAppender }, undefined!);
|
||||
|
||||
@@ -193,7 +196,7 @@ suite('TelemetryService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('enableTelemetry on by default', sinon.test(function () {
|
||||
test('enableTelemetry on by default', sinonTestFn(function () {
|
||||
let testAppender = new TestTelemetryAppender();
|
||||
let service = new TelemetryService({ appender: testAppender }, undefined!);
|
||||
|
||||
@@ -224,7 +227,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}
|
||||
|
||||
test('Error events', sinon.test(async function (this: any) {
|
||||
test('Error events', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -256,7 +259,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
// test('Unhandled Promise Error events', sinon.test(function() {
|
||||
// test('Unhandled Promise Error events', sinonTestFn(function() {
|
||||
//
|
||||
// let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
// Errors.setUnexpectedErrorHandler(() => {});
|
||||
@@ -285,7 +288,7 @@ suite('TelemetryService', () => {
|
||||
// }
|
||||
// }));
|
||||
|
||||
test('Handle global errors', sinon.test(async function (this: any) {
|
||||
test('Handle global errors', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
|
||||
@@ -313,7 +316,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Error Telemetry removes PII from filename with spaces', sinon.test(async function (this: any) {
|
||||
test('Error Telemetry removes PII from filename with spaces', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -336,7 +339,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII from filename', sinon.test(function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII from filename', sinonTestFn(function (this: any) {
|
||||
let clock = this.clock;
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
@@ -368,7 +371,7 @@ suite('TelemetryService', () => {
|
||||
});
|
||||
}));
|
||||
|
||||
test('Unexpected Error Telemetry removes PII', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII', sinonTestFn(async function (this: any) {
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
try {
|
||||
@@ -399,7 +402,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -426,7 +429,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -462,7 +465,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -491,7 +494,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path with node modules', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path with node modules', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -523,7 +526,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -549,7 +552,7 @@ suite('TelemetryService', () => {
|
||||
}));
|
||||
|
||||
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path when PIIPath is configured', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII but preserves Code file path when PIIPath is configured', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -585,7 +588,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path when PIIPath is configured', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII but preserves Code file path when PIIPath is configured', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -614,7 +617,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Unexpected Error Telemetry removes PII but preserves Missing Model error message', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII but preserves Missing Model error message', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -650,7 +653,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII but preserves Missing Model error message', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII but preserves Missing Model error message', sinonTestFn(async function (this: any) {
|
||||
let errorStub = sinon.stub();
|
||||
window.onerror = errorStub;
|
||||
let settings = new ErrorTestingSettings();
|
||||
@@ -680,7 +683,7 @@ suite('TelemetryService', () => {
|
||||
service.dispose();
|
||||
}));
|
||||
|
||||
test('Unexpected Error Telemetry removes PII but preserves No Such File error message', sinon.test(async function (this: any) {
|
||||
test('Unexpected Error Telemetry removes PII but preserves No Such File error message', sinonTestFn(async function (this: any) {
|
||||
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
@@ -716,7 +719,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Uncaught Error Telemetry removes PII but preserves No Such File error message', sinon.test(async function (this: any) {
|
||||
test('Uncaught Error Telemetry removes PII but preserves No Such File error message', sinonTestFn(async function (this: any) {
|
||||
let origErrorHandler = Errors.errorHandler.getUnexpectedErrorHandler();
|
||||
Errors.setUnexpectedErrorHandler(() => { });
|
||||
|
||||
@@ -754,7 +757,7 @@ suite('TelemetryService', () => {
|
||||
}
|
||||
}));
|
||||
|
||||
test('Telemetry Service sends events when enableTelemetry is on', sinon.test(function () {
|
||||
test('Telemetry Service sends events when enableTelemetry is on', sinonTestFn(function () {
|
||||
let testAppender = new TestTelemetryAppender();
|
||||
let service = new TelemetryService({ appender: testAppender }, undefined!);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import { createCancelablePromise, timeout, CancelablePromise } from 'vs/base/com
|
||||
import { isString, isObject, isArray } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
const SYNC_PREVIOUS_STORE = 'sync.previous.store';
|
||||
const DONOT_MAKE_REQUESTS_UNTIL_KEY = 'sync.donot-make-requests-until';
|
||||
@@ -304,7 +305,7 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource', resource).toString();
|
||||
headers = { ...headers };
|
||||
headers['Content-Type'] = 'text/plain';
|
||||
headers['Content-Type'] = Mimes.text;
|
||||
if (ref) {
|
||||
headers['If-Match'] = ref;
|
||||
}
|
||||
@@ -356,7 +357,7 @@ export class UserDataSyncStoreClient extends Disposable implements IUserDataSync
|
||||
}
|
||||
|
||||
const url = joinPath(this.userDataSyncStoreUrl, 'resource').toString();
|
||||
const headers: IHeaders = { 'Content-Type': 'text/plain' };
|
||||
const headers: IHeaders = { 'Content-Type': Mimes.text };
|
||||
|
||||
await this.request(url, { type: 'DELETE', headers }, [], CancellationToken.None);
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getMediaMime, MIME_UNKNOWN } from 'vs/base/common/mime';
|
||||
import { getMediaMime, Mimes } from 'vs/base/common/mime';
|
||||
import { extname } from 'vs/base/common/path';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
const webviewMimeTypes = new Map([
|
||||
['.svg', 'image/svg+xml'],
|
||||
['.txt', 'text/plain'],
|
||||
['.txt', Mimes.text],
|
||||
['.css', 'text/css'],
|
||||
['.js', 'application/javascript'],
|
||||
['.json', 'application/json'],
|
||||
@@ -18,9 +18,10 @@ const webviewMimeTypes = new Map([
|
||||
['.xhtml', 'application/xhtml+xml'],
|
||||
['.oft', 'font/otf'],
|
||||
['.xml', 'application/xml'],
|
||||
['.wasm', 'application/wasm'],
|
||||
]);
|
||||
|
||||
export function getWebviewContentMimeType(resource: URI): string {
|
||||
const ext = extname(resource.fsPath).toLowerCase();
|
||||
return webviewMimeTypes.get(ext) || getMediaMime(resource.fsPath) || MIME_UNKNOWN;
|
||||
return webviewMimeTypes.get(ext) || getMediaMime(resource.fsPath) || Mimes.unknown;
|
||||
}
|
||||
|
||||
Vendored
+28
-10
@@ -9489,6 +9489,24 @@ declare module 'vscode' {
|
||||
*/
|
||||
onDidClose?: Event<void | number>;
|
||||
|
||||
/**
|
||||
* An event that when fired allows changing the name of the terminal.
|
||||
*
|
||||
* **Example:** Change the terminal name to "My new terminal".
|
||||
* ```typescript
|
||||
* const writeEmitter = new vscode.EventEmitter<string>();
|
||||
* const changeNameEmitter = new vscode.EventEmitter<string>();
|
||||
* const pty: vscode.Pseudoterminal = {
|
||||
* onDidWrite: writeEmitter.event,
|
||||
* onDidChangeName: changeNameEmitter.event,
|
||||
* open: () => changeNameEmitter.fire('My new terminal'),
|
||||
* close: () => {}
|
||||
* };
|
||||
* vscode.window.createTerminal({ name: 'My terminal', pty });
|
||||
* ```
|
||||
*/
|
||||
onDidChangeName?: Event<string>;
|
||||
|
||||
/**
|
||||
* Implement to handle when the pty is open and ready to start firing events.
|
||||
*
|
||||
@@ -9884,7 +9902,7 @@ declare module 'vscode' {
|
||||
/**
|
||||
* An event signaling when the active items have changed.
|
||||
*/
|
||||
readonly onDidChangeActive: Event<T[]>;
|
||||
readonly onDidChangeActive: Event<readonly T[]>;
|
||||
|
||||
/**
|
||||
* Selected items. This can be read and updated by the extension.
|
||||
@@ -9894,7 +9912,7 @@ declare module 'vscode' {
|
||||
/**
|
||||
* An event signaling when the selected items have changed.
|
||||
*/
|
||||
readonly onDidChangeSelection: Event<T[]>;
|
||||
readonly onDidChangeSelection: Event<readonly T[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -11409,7 +11427,7 @@ declare module 'vscode' {
|
||||
readonly outputs: readonly NotebookCellOutput[];
|
||||
|
||||
/**
|
||||
* The most recent {@link NotebookCellExecutionSummary excution summary} for this cell.
|
||||
* The most recent {@link NotebookCellExecutionSummary execution summary} for this cell.
|
||||
*/
|
||||
readonly executionSummary?: NotebookCellExecutionSummary;
|
||||
}
|
||||
@@ -11477,7 +11495,7 @@ declare module 'vscode' {
|
||||
|
||||
/**
|
||||
* Get the cells of this notebook. A subset can be retrieved by providing
|
||||
* a range. The range will be adjuset to the notebook.
|
||||
* a range. The range will be adjusted to the notebook.
|
||||
*
|
||||
* @param range A notebook range.
|
||||
* @returns The cells contained by the range or all cells.
|
||||
@@ -11515,7 +11533,7 @@ declare module 'vscode' {
|
||||
}
|
||||
|
||||
/**
|
||||
* A notebook range represents an ordered pair of two cell indicies.
|
||||
* A notebook range represents an ordered pair of two cell indices.
|
||||
* It is guaranteed that start is less than or equal to end.
|
||||
*/
|
||||
export class NotebookRange {
|
||||
@@ -11626,7 +11644,7 @@ declare module 'vscode' {
|
||||
data: Uint8Array;
|
||||
|
||||
/**
|
||||
* Create a new notbook cell output item.
|
||||
* Create a new notebook cell output item.
|
||||
*
|
||||
* @param data The value of the output item.
|
||||
* @param mime The mime type of the output item.
|
||||
@@ -12122,7 +12140,7 @@ declare module 'vscode' {
|
||||
/**
|
||||
* Namespace for notebooks.
|
||||
*
|
||||
* The notebooks functionality is composed of three loosly coupled components:
|
||||
* The notebooks functionality is composed of three loosely coupled components:
|
||||
*
|
||||
* 1. {@link NotebookSerializer} enable the editor to open, show, and save notebooks
|
||||
* 2. {@link NotebookController} own the execution of notebooks, e.g they create output from code cells.
|
||||
@@ -13512,17 +13530,17 @@ declare module 'vscode' {
|
||||
*/
|
||||
export interface AuthenticationProviderAuthenticationSessionsChangeEvent {
|
||||
/**
|
||||
* The {@link AuthenticationSession}s of the {@link AuthentiationProvider AuthenticationProvider} that have been added.
|
||||
* The {@link AuthenticationSession}s of the {@link AuthenticationProvider} that have been added.
|
||||
*/
|
||||
readonly added?: readonly AuthenticationSession[];
|
||||
|
||||
/**
|
||||
* The {@link AuthenticationSession}s of the {@link AuthentiationProvider AuthenticationProvider} that have been removed.
|
||||
* The {@link AuthenticationSession}s of the {@link AuthenticationProvider} that have been removed.
|
||||
*/
|
||||
readonly removed?: readonly AuthenticationSession[];
|
||||
|
||||
/**
|
||||
* The {@link AuthenticationSession}s of the {@link AuthentiationProvider AuthenticationProvider} that have been changed.
|
||||
* The {@link AuthenticationSession}s of the {@link AuthenticationProvider} that have been changed.
|
||||
* A session changes when its data excluding the id are updated. An example of this is a session refresh that results in a new
|
||||
* access token being set for the session.
|
||||
*/
|
||||
|
||||
Vendored
-24
@@ -874,30 +874,6 @@ declare module 'vscode' {
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Terminal name change event https://github.com/microsoft/vscode/issues/114898
|
||||
|
||||
export interface Pseudoterminal {
|
||||
/**
|
||||
* An event that when fired allows changing the name of the terminal.
|
||||
*
|
||||
* **Example:** Change the terminal name to "My new terminal".
|
||||
* ```typescript
|
||||
* const writeEmitter = new vscode.EventEmitter<string>();
|
||||
* const changeNameEmitter = new vscode.EventEmitter<string>();
|
||||
* const pty: vscode.Pseudoterminal = {
|
||||
* onDidWrite: writeEmitter.event,
|
||||
* onDidChangeName: changeNameEmitter.event,
|
||||
* open: () => changeNameEmitter.fire('My new terminal'),
|
||||
* close: () => {}
|
||||
* };
|
||||
* vscode.window.createTerminal({ name: 'My terminal', pty });
|
||||
* ```
|
||||
*/
|
||||
onDidChangeName?: Event<string>;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region Terminal icon https://github.com/microsoft/vscode/issues/120538
|
||||
|
||||
export interface TerminalOptions {
|
||||
|
||||
@@ -551,7 +551,7 @@ export abstract class AbstractExtHostExtensionService extends Disposable impleme
|
||||
public async $extensionTestsExecute(): Promise<number> {
|
||||
await this._eagerExtensionsActivated.wait();
|
||||
try {
|
||||
return this._doHandleExtensionTests();
|
||||
return await this._doHandleExtensionTests();
|
||||
} catch (error) {
|
||||
console.error(error); // ensure any error message makes it onto the console
|
||||
throw error;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { illegalArgument } from 'vs/base/common/errors';
|
||||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { isMarkdownString, MarkdownString as BaseMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { ReadonlyMapView, ResourceMap } from 'vs/base/common/map';
|
||||
import { normalizeMimeType } from 'vs/base/common/mime';
|
||||
import { Mimes, normalizeMimeType } from 'vs/base/common/mime';
|
||||
import { isArray, isStringArray } from 'vs/base/common/types';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
@@ -3050,7 +3050,7 @@ export class NotebookCellOutputItem {
|
||||
|
||||
static #encoder = new TextEncoder();
|
||||
|
||||
static text(value: string, mime: string = 'text/plain'): NotebookCellOutputItem {
|
||||
static text(value: string, mime: string = Mimes.text): NotebookCellOutputItem {
|
||||
const bytes = NotebookCellOutputItem.#encoder.encode(String(value));
|
||||
return new NotebookCellOutputItem(bytes, mime);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { FileAccess, Schemas } from 'vs/base/common/network';
|
||||
import { IBaseTextResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { DragMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { MIME_BINARY } from 'vs/base/common/mime';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
@@ -277,7 +277,7 @@ export function fillEditorsDragData(accessor: ServicesAccessor, resourcesOrEdito
|
||||
// TODO@sandbox this will no longer work when `vscode-file`
|
||||
// is enabled because we block loading resources that are not
|
||||
// inside installation dir
|
||||
event.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [MIME_BINARY, basename(firstFile.resource), FileAccess.asBrowserUri(firstFile.resource).toString()].join(':'));
|
||||
event.dataTransfer.setData(DataTransfers.DOWNLOAD_URL, [Mimes.binary, basename(firstFile.resource), FileAccess.asBrowserUri(firstFile.resource).toString()].join(':'));
|
||||
}
|
||||
|
||||
// Resource URLs: allows to drop multiple file resources to a target in VS Code
|
||||
|
||||
@@ -22,6 +22,7 @@ import { ViewContainerLocation, IViewDescriptorService } from 'vs/workbench/comm
|
||||
import { IPaneComposite } from 'vs/workbench/common/panecomposite';
|
||||
import { IComposite } from 'vs/workbench/common/composite';
|
||||
import { CompositeDragAndDropData, CompositeDragAndDropObserver, IDraggedCompositeData, ICompositeDragAndDrop, Before2D, toggleDropEffect } from 'vs/workbench/browser/dnd';
|
||||
import { Gesture, EventType as TouchEventType, GestureEvent } from 'vs/base/browser/touch';
|
||||
|
||||
export interface ICompositeBarItem {
|
||||
id: string;
|
||||
@@ -233,6 +234,8 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
|
||||
// Contextmenu for composites
|
||||
this._register(addDisposableListener(parent, EventType.CONTEXT_MENU, e => this.showContextMenu(e)));
|
||||
this._register(Gesture.addTarget(parent));
|
||||
this._register(addDisposableListener(parent, TouchEventType.Contextmenu, e => this.showContextMenu(e)));
|
||||
|
||||
let insertDropBefore: Before2D | undefined = undefined;
|
||||
// Register a drop target on the whole bar to prevent forbidden feedback
|
||||
@@ -619,7 +622,7 @@ export class CompositeBar extends Widget implements ICompositeBar {
|
||||
return this.model.visibleItems.filter(c => overflowingIds.includes(c.id)).map(item => { return { id: item.id, name: this.getAction(item.id)?.label || item.name }; });
|
||||
}
|
||||
|
||||
private showContextMenu(e: MouseEvent): void {
|
||||
private showContextMenu(e: MouseEvent | GestureEvent): void {
|
||||
EventHelper.stop(e, true);
|
||||
const event = new StandardMouseEvent(e);
|
||||
this.contextMenuService.showContextMenu({
|
||||
|
||||
@@ -22,7 +22,6 @@ import { Color } from 'vs/base/common/color';
|
||||
import { IBaseActionViewItemOptions, BaseActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { IHoverService } from 'vs/workbench/services/hover/browser/hover';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
|
||||
@@ -395,15 +394,15 @@ export class ActivityActionViewItem extends BaseActionViewItem {
|
||||
|
||||
this.updateTitle();
|
||||
if (this.useCustomHover) {
|
||||
this.hoverDisposables.add(domEvent(this.container, EventType.MOUSE_OVER, true)(() => {
|
||||
this.hoverDisposables.add(addDisposableListener(this.container, EventType.MOUSE_OVER, () => {
|
||||
if (!this.showHoverScheduler.isScheduled()) {
|
||||
this.showHoverScheduler.schedule(this.options.hoverOptions!.delay() || 150);
|
||||
}
|
||||
}));
|
||||
this.hoverDisposables.add(domEvent(this.container, EventType.MOUSE_LEAVE, true)(() => {
|
||||
}, true));
|
||||
this.hoverDisposables.add(addDisposableListener(this.container, EventType.MOUSE_LEAVE, () => {
|
||||
this.hover.value = undefined;
|
||||
this.showHoverScheduler.cancel();
|
||||
}));
|
||||
}, true));
|
||||
this.hoverDisposables.add(toDisposable(() => {
|
||||
this.hover.value = undefined;
|
||||
this.showHoverScheduler.cancel();
|
||||
|
||||
@@ -35,6 +35,7 @@ import { CompositeDragAndDropObserver } from 'vs/workbench/browser/dnd';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { CATEGORIES } from 'vs/workbench/common/actions';
|
||||
import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
|
||||
|
||||
export class SidebarPart extends CompositePart<Viewlet> implements IViewletService {
|
||||
|
||||
@@ -171,6 +172,10 @@ export class SidebarPart extends CompositePart<Viewlet> implements IViewletServi
|
||||
this._register(addDisposableListener(titleArea, EventType.CONTEXT_MENU, e => {
|
||||
this.onTitleAreaContextMenu(new StandardMouseEvent(e));
|
||||
}));
|
||||
this._register(Gesture.addTarget(titleArea));
|
||||
this._register(addDisposableListener(titleArea, GestureEventType.Contextmenu, e => {
|
||||
this.onTitleAreaContextMenu(new StandardMouseEvent(e));
|
||||
}));
|
||||
|
||||
this.titleLabelElement!.draggable = true;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import { dispose, IDisposable, Disposable, toDisposable, MutableDisposable } fro
|
||||
import { SimpleIconLabel } from 'vs/base/browser/ui/iconLabel/simpleIconLabel';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { Part } from 'vs/workbench/browser/part';
|
||||
import { EventType as TouchEventType, Gesture, GestureEvent } from 'vs/base/browser/touch';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { StatusbarAlignment, IStatusbarService, IStatusbarEntry, IStatusbarEntryAccessor } from 'vs/workbench/services/statusbar/common/statusbar';
|
||||
@@ -586,6 +587,8 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
|
||||
// Context menu support
|
||||
this._register(addDisposableListener(parent, EventType.CONTEXT_MENU, e => this.showContextMenu(e)));
|
||||
this._register(Gesture.addTarget(parent));
|
||||
this._register(addDisposableListener(parent, TouchEventType.Contextmenu, e => this.showContextMenu(e)));
|
||||
|
||||
// Initial status bar entries
|
||||
this.createInitialStatusbarEntries();
|
||||
@@ -660,7 +663,7 @@ export class StatusbarPart extends Part implements IStatusbarService {
|
||||
}
|
||||
}
|
||||
|
||||
private showContextMenu(e: MouseEvent): void {
|
||||
private showContextMenu(e: MouseEvent | GestureEvent): void {
|
||||
EventHelper.stop(e, true);
|
||||
|
||||
const event = new StandardMouseEvent(e);
|
||||
|
||||
@@ -38,6 +38,7 @@ import { ViewPane } from 'vs/workbench/browser/parts/views/viewPane';
|
||||
import { CompositeMenuActions } from 'vs/workbench/browser/actions';
|
||||
import { createActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
|
||||
import { IActionViewItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch';
|
||||
|
||||
export const ViewsSubMenu = new MenuId('Views');
|
||||
MenuRegistry.appendMenuItem(MenuId.ViewContainerTitle, <ISubmenuItem>{
|
||||
@@ -409,6 +410,8 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer {
|
||||
this._register(this.paneview.onDidDrop(({ from, to }) => this.movePane(from as ViewPane, to as ViewPane)));
|
||||
this._register(this.paneview.onDidScroll(_ => this.onDidScrollPane()));
|
||||
this._register(addDisposableListener(parent, EventType.CONTEXT_MENU, (e: MouseEvent) => this.showContextMenu(new StandardMouseEvent(e))));
|
||||
this._register(Gesture.addTarget(parent));
|
||||
this._register(addDisposableListener(parent, TouchEventType.Contextmenu, (e: MouseEvent) => this.showContextMenu(new StandardMouseEvent(e))));
|
||||
|
||||
this._menuActions = this._register(this.instantiationService.createInstance(ViewContainerMenuActions, this.paneview.element, this.viewContainer));
|
||||
this._register(this._menuActions.onDidChange(() => this.updateTitleArea()));
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { MIME_BINARY } from 'vs/base/common/mime';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
/**
|
||||
* An editor model that just represents a resource that can be loaded.
|
||||
*/
|
||||
export class BinaryEditorModel extends EditorModel {
|
||||
|
||||
private readonly mime = MIME_BINARY;
|
||||
private readonly mime = Mimes.binary;
|
||||
|
||||
private size: number | undefined;
|
||||
private etag: string | undefined;
|
||||
|
||||
@@ -233,9 +233,10 @@ class FormatOnSaveParticipant implements ITextFileSaveParticipant {
|
||||
const nestedProgress = new Progress<{ displayName?: string, extensionId?: ExtensionIdentifier }>(provider => {
|
||||
progress.report({
|
||||
message: localize(
|
||||
'formatting',
|
||||
"Running '{0}' Formatter ([configure](command:workbench.action.openSettings?%5B%22editor.formatOnSave%22%5D)).",
|
||||
provider.displayName || provider.extensionId && provider.extensionId.value || '???'
|
||||
{ key: 'formatting2', comment: ['[configure]({1}) is a link. Only translate `configure`. Do not change brackets and parentheses or {1}'] },
|
||||
"Running '{0}' Formatter ([configure]({1})).",
|
||||
provider.displayName || provider.extensionId && provider.extensionId.value || '???',
|
||||
'command:workbench.action.openSettings?%5B%22editor.formatOnSave%22%5D'
|
||||
)
|
||||
});
|
||||
});
|
||||
@@ -336,9 +337,10 @@ class CodeActionOnSaveParticipant implements ITextFileSaveParticipant {
|
||||
private _report(): void {
|
||||
progress.report({
|
||||
message: localize(
|
||||
'codeaction.get',
|
||||
"Getting code actions from '{0}' ([configure](command:workbench.action.openSettings?%5B%22editor.codeActionsOnSave%22%5D)).",
|
||||
[...this._names].map(name => `'${name}'`).join(', ')
|
||||
{ key: 'codeaction.get2', comment: ['[configure]({1}) is a link. Only translate `configure`. Do not change brackets and parentheses or {1}'] },
|
||||
"Getting code actions from '{0}' ([configure]({1})).",
|
||||
[...this._names].map(name => `'${name}'`).join(', '),
|
||||
'command:workbench.action.openSettings?%5B%22editor.codeActionsOnSave%22%5D'
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ class UntitledTextEditorHintContentWidget implements IContentWidget {
|
||||
this.domNode.style.width = 'max-content';
|
||||
const language = $('a.language-mode');
|
||||
language.style.cursor = 'pointer';
|
||||
language.innerText = localize('selectAlanguage', "Select a language");
|
||||
language.innerText = localize('selectAlanguage2', "Select a language");
|
||||
this.domNode.appendChild(language);
|
||||
const toGetStarted = $('span');
|
||||
toGetStarted.innerText = localize('toGetStarted', " to get started. Start typing to dismiss, or ",);
|
||||
|
||||
@@ -21,6 +21,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ADD_CONFIGURATION_ID } from 'vs/workbench/contrib/debug/browser/debugCommands';
|
||||
import { BaseActionViewItem, SelectActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { debugStart } from 'vs/workbench/contrib/debug/browser/debugIcons';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -45,6 +46,7 @@ export class StartDebugActionViewItem extends BaseActionViewItem {
|
||||
@ICommandService private readonly commandService: ICommandService,
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IContextViewService contextViewService: IContextViewService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
super(context, action);
|
||||
this.toDispose = [];
|
||||
@@ -71,7 +73,9 @@ export class StartDebugActionViewItem extends BaseActionViewItem {
|
||||
this.container = container;
|
||||
container.classList.add('start-debug-action-item');
|
||||
this.start = dom.append(container, $(ThemeIcon.asCSSSelector(debugStart)));
|
||||
this.start.title = this.action.label;
|
||||
const keybinding = this.keybindingService.lookupKeybinding(this.action.id)?.getLabel();
|
||||
let keybindingLabel = keybinding ? ` (${keybinding})` : '';
|
||||
this.start.title = this.action.label + keybindingLabel;
|
||||
this.start.setAttribute('role', 'button');
|
||||
|
||||
this.toDispose.push(dom.addDisposableListener(this.start, dom.EventType.CLICK, () => {
|
||||
|
||||
@@ -37,7 +37,6 @@ import { ITextModel } from 'vs/editor/common/model';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { ModesHoverController } from 'vs/editor/contrib/hover/hover';
|
||||
import { HoverStartMode } from 'vs/editor/contrib/hover/hoverOperation';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
@@ -47,6 +46,8 @@ import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/c
|
||||
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
const LAUNCH_JSON_REGEX = /\.vscode\/launch\.json$/;
|
||||
const INLINE_VALUE_DECORATION_KEY = 'inlinevaluedecoration';
|
||||
@@ -284,7 +285,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
|
||||
this.altListener.dispose();
|
||||
}
|
||||
// When the alt key is pressed show regular editor hover and hide the debug hover #84561
|
||||
this.altListener = domEvent(document, 'keydown')(keydownEvent => {
|
||||
this.altListener = addDisposableListener(document, 'keydown', keydownEvent => {
|
||||
const standardKeyboardEvent = new StandardKeyboardEvent(keydownEvent);
|
||||
if (standardKeyboardEvent.keyCode === KeyCode.Alt) {
|
||||
this.altPressed = true;
|
||||
@@ -297,7 +298,8 @@ export class DebugEditorContribution implements IDebugEditorContribution {
|
||||
hoverController.showContentHover(this.hoverRange, HoverStartMode.Immediate, false);
|
||||
}
|
||||
|
||||
const listener = Event.any<KeyboardEvent | boolean>(this.hostService.onDidChangeFocus, domEvent(document, 'keyup'))(keyupEvent => {
|
||||
const onKeyUp = new DomEmitter(document, 'keyup');
|
||||
const listener = Event.any<KeyboardEvent | boolean>(this.hostService.onDidChangeFocus, onKeyUp.event)(keyupEvent => {
|
||||
let standardKeyboardEvent = undefined;
|
||||
if (keyupEvent instanceof KeyboardEvent) {
|
||||
standardKeyboardEvent = new StandardKeyboardEvent(keyupEvent);
|
||||
@@ -306,6 +308,7 @@ export class DebugEditorContribution implements IDebugEditorContribution {
|
||||
this.altPressed = false;
|
||||
this.editor.updateOptions({ hover: { enabled: false } });
|
||||
listener.dispose();
|
||||
onKeyUp.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import { localize } from 'vs/nls';
|
||||
import { guessMimeTypes, MIME_TEXT } from 'vs/base/common/mime';
|
||||
import { guessMimeTypes, Mimes } from 'vs/base/common/mime';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
@@ -94,7 +94,7 @@ export class DebugContentProvider implements IWorkbenchContribution, ITextModelC
|
||||
}
|
||||
const createErrModel = (errMsg?: string) => {
|
||||
this.debugService.sourceIsNotAvailable(resource);
|
||||
const languageSelection = this.modeService.create(MIME_TEXT);
|
||||
const languageSelection = this.modeService.create(Mimes.text);
|
||||
const message = errMsg
|
||||
? localize('canNotResolveSourceWithError', "Could not load source '{0}': {1}.", resource.path, errMsg)
|
||||
: localize('canNotResolveSource', "Could not load source '{0}'.", resource.path);
|
||||
|
||||
@@ -41,7 +41,7 @@ export function filterExceptionsFromTelemetry<T extends { [key: string]: unknown
|
||||
|
||||
|
||||
export function isSessionAttach(session: IDebugSession): boolean {
|
||||
return session.configuration.request === 'attach' && !getExtensionHostDebugSession(session);
|
||||
return session.configuration.request === 'attach' && !getExtensionHostDebugSession(session) && (!session.parentSession || isSessionAttach(session.parentSession));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IExtensionService, IExtensionsStatus, IExtensionHostProfile } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
|
||||
import { WorkbenchList } from 'vs/platform/list/browser/listService';
|
||||
import { append, $, reset, Dimension, clearNode } from 'vs/base/browser/dom';
|
||||
import { append, $, reset, Dimension, clearNode, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
@@ -22,7 +22,6 @@ import { EnablementState } from 'vs/workbench/services/extensionManagement/commo
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
@@ -32,7 +31,6 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { editorBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { RuntimeExtensionsInput } from 'vs/workbench/contrib/extensions/common/runtimeExtensionsInput';
|
||||
@@ -267,8 +265,7 @@ export abstract class AbstractRuntimeExtensionsEditor extends EditorPane {
|
||||
|
||||
data.root.classList.toggle('odd', index % 2 === 1);
|
||||
|
||||
const onError = Event.once(domEvent(data.icon, 'error'));
|
||||
onError(() => data.icon.src = element.marketplaceInfo?.iconUrlFallback || DefaultIconPath, null, data.elementDisposables);
|
||||
data.elementDisposables.push(addDisposableListener(data.icon, 'error', () => data.icon.src = element.marketplaceInfo?.iconUrlFallback || DefaultIconPath, { once: true }));
|
||||
data.icon.src = element.marketplaceInfo?.iconUrl || DefaultIconPath;
|
||||
|
||||
if (!data.icon.complete) {
|
||||
|
||||
@@ -13,7 +13,6 @@ import { Cache, CacheResult } from 'vs/base/common/cache';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { dispose, toDisposable, Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { append, $, finalHandler, join, hide, show, addDisposableListener, EventType, setParentFlowTo } from 'vs/base/browser/dom';
|
||||
import { EditorPane } from 'vs/workbench/browser/parts/editor/editorPane';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
@@ -349,8 +348,7 @@ export class ExtensionEditor extends EditorPane {
|
||||
this.extensionManifest = new Cache(() => createCancelablePromise(token => extension.getManifest(token)));
|
||||
|
||||
const remoteBadge = this.instantiationService.createInstance(RemoteBadgeWidget, template.iconContainer, true);
|
||||
const onError = Event.once(domEvent(template.icon, 'error'));
|
||||
onError(() => template.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
|
||||
this.transientDisposables.add(addDisposableListener(template.icon, 'error', () => template.icon.src = extension.iconUrlFallback, { once: true }));
|
||||
template.icon.src = extension.iconUrl;
|
||||
|
||||
template.name.textContent = extension.displayName;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./media/extension';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
import { append, $, addDisposableListener } from 'vs/base/browser/dom';
|
||||
import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
@@ -12,7 +12,6 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IExtension, ExtensionContainers, ExtensionState, IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { UpdateAction, ManageExtensionAction, ReloadAction, MaliciousStatusLabelAction, StatusLabelAction, RemoteInstallAction, SystemDisabledWarningAction, ExtensionToolTipAction, LocalInstallAction, ActionWithDropDownAction, InstallDropdownAction, InstallingLabelAction, ExtensionActionWithDropdownActionViewItem, ExtensionDropDownAction, WebInstallAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
@@ -190,8 +189,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
|
||||
updateEnablement();
|
||||
this.extensionService.onDidChangeExtensions(() => updateEnablement(), this, data.extensionDisposables);
|
||||
|
||||
const onError = Event.once(domEvent(data.icon, 'error'));
|
||||
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
|
||||
data.extensionDisposables.push(addDisposableListener(data.icon, 'error', () => data.icon.src = extension.iconUrlFallback, { once: true }));
|
||||
data.icon.src = extension.iconUrl;
|
||||
|
||||
if (!data.icon.complete) {
|
||||
|
||||
@@ -9,7 +9,6 @@ import { IDisposable, dispose, Disposable, DisposableStore, toDisposable } from
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IExtensionsWorkbenchService, IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IListService, WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -167,8 +166,7 @@ export class ExtensionRenderer implements IListRenderer<ITreeNode<IExtensionData
|
||||
|
||||
public renderElement(node: ITreeNode<IExtensionData>, index: number, data: IExtensionTemplateData): void {
|
||||
const extension = node.element.extension;
|
||||
const onError = Event.once(domEvent(data.icon, 'error'));
|
||||
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
|
||||
data.extensionDisposables.push(dom.addDisposableListener(data.icon, 'error', () => data.icon.src = extension.iconUrlFallback, { once: true }));
|
||||
data.icon.src = extension.iconUrl;
|
||||
|
||||
if (!data.icon.complete) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Schemas } from 'vs/base/common/network';
|
||||
import { basename, extname } from 'vs/base/common/resources';
|
||||
import { match } from 'vs/base/common/glob';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { MIME_UNKNOWN, guessMimeTypes } from 'vs/base/common/mime';
|
||||
import { Mimes, guessMimeTypes } from 'vs/base/common/mime';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
@@ -230,7 +230,7 @@ export class FileBasedRecommendations extends ExtensionRecommendations {
|
||||
}
|
||||
|
||||
const mimeTypes = guessMimeTypes(uri);
|
||||
if (mimeTypes.length !== 1 || mimeTypes[0] !== MIME_UNKNOWN) {
|
||||
if (mimeTypes.length !== 1 || mimeTypes[0] !== Mimes.unknown) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -487,12 +487,13 @@ export class ExplorerView extends ViewPane {
|
||||
}
|
||||
|
||||
private setContextKeys(stat: ExplorerItem | null | undefined): void {
|
||||
const isSingleFolder = this.contextService.getWorkbenchState() === WorkbenchState.FOLDER;
|
||||
const resource = stat ? stat.resource : isSingleFolder ? this.contextService.getWorkspace().folders[0].uri : null;
|
||||
const folders = this.contextService.getWorkspace().folders;
|
||||
const resource = stat ? stat.resource : folders[folders.length - 1].uri;
|
||||
stat = stat || this.explorerService.findClosest(resource);
|
||||
this.resourceContext.set(resource);
|
||||
this.folderContext.set((isSingleFolder && !stat) || !!stat && stat.isDirectory);
|
||||
this.folderContext.set(!!stat && stat.isDirectory);
|
||||
this.readonlyContext.set(!!stat && stat.isReadonly);
|
||||
this.rootContext.set(!stat || (stat && stat.isRoot));
|
||||
this.rootContext.set(!!stat && stat.isRoot);
|
||||
|
||||
if (resource) {
|
||||
const overrides = resource ? this.editorOverrideService.getEditorIds(resource) : [];
|
||||
|
||||
@@ -49,7 +49,6 @@ import { ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { isNumber } from 'vs/base/common/types';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IEditableData } from 'vs/workbench/common/views';
|
||||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
|
||||
@@ -328,13 +327,13 @@ export class FilesRenderer implements ICompressibleTreeRenderer<ExplorerItem, Fu
|
||||
// accessibility
|
||||
disposables.add(this._onDidChangeActiveDescendant.add(compressedNavigationController.onDidChange));
|
||||
|
||||
domEvent(templateData.container, 'mousedown')(e => {
|
||||
disposables.add(DOM.addDisposableListener(templateData.container, 'mousedown', e => {
|
||||
const result = getIconLabelNameFromHTMLElement(e.target);
|
||||
|
||||
if (result) {
|
||||
compressedNavigationController.setIndex(result.index);
|
||||
}
|
||||
}, undefined, disposables);
|
||||
}));
|
||||
|
||||
disposables.add(toDisposable(() => this.compressedNavigationControllers.delete(stat)));
|
||||
|
||||
|
||||
@@ -48,13 +48,13 @@ import { textLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { OS, OperatingSystem } from 'vs/base/common/platform';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Progress } from 'vs/platform/progress/common/progress';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { DomEmitter } from 'vs/base/browser/event';
|
||||
|
||||
interface IResourceMarkersTemplateData {
|
||||
resourceLabel: IResourceLabel;
|
||||
@@ -417,10 +417,10 @@ class MarkerWidget extends Disposable {
|
||||
this._codeLink.setAttribute('href', codeLink);
|
||||
this._codeLink.tabIndex = 0;
|
||||
|
||||
const onClick = Event.chain(domEvent(this._codeLink, 'click'))
|
||||
const onClick = Event.chain(this._register(new DomEmitter(this._codeLink, 'click')).event)
|
||||
.filter(e => ((this._clickModifierKey === 'meta' && e.metaKey) || (this._clickModifierKey === 'ctrl' && e.ctrlKey) || (this._clickModifierKey === 'alt' && e.altKey)))
|
||||
.event;
|
||||
const onEnterPress = Event.chain(domEvent(this._codeLink, 'keydown'))
|
||||
const onEnterPress = Event.chain(this._register(new DomEmitter(this._codeLink, 'keydown')).event)
|
||||
.map(e => new StandardKeyboardEvent(e))
|
||||
.filter(e => e.keyCode === KeyCode.Enter)
|
||||
.event;
|
||||
|
||||
@@ -36,7 +36,6 @@ import { ActionBar, IActionViewItem } from 'vs/base/browser/ui/actionbar/actionb
|
||||
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
import { IMarker, IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
@@ -443,7 +442,7 @@ export class MarkersView extends ViewPane implements IMarkersView {
|
||||
}));
|
||||
|
||||
// move focus to input, whenever a key is pressed in the panel container
|
||||
this._register(domEvent(parent, 'keydown')(e => {
|
||||
this._register(dom.addDisposableListener(parent, 'keydown', e => {
|
||||
if (this.keybindingService.mightProducePrintableCharacter(new StandardKeyboardEvent(e))) {
|
||||
this.focusFilter();
|
||||
}
|
||||
|
||||
@@ -263,6 +263,7 @@ export interface ICellViewModel extends IGenericCellViewModel {
|
||||
handle: number;
|
||||
uri: URI;
|
||||
language: string;
|
||||
readonly mime: string;
|
||||
cellKind: CellKind;
|
||||
lineNumbers: 'on' | 'off' | 'inherit';
|
||||
focusMode: CellFocusMode;
|
||||
|
||||
@@ -72,6 +72,7 @@ import { NotebookOptions } from 'vs/workbench/contrib/notebook/common/notebookOp
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
import { NotebookEditorToolbar } from 'vs/workbench/contrib/notebook/browser/notebookEditorToolbar';
|
||||
import { INotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService';
|
||||
import { IMarkupCellInitialization } from 'vs/workbench/contrib/notebook/browser/view/renderers/webviewMessages';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -1385,18 +1386,13 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
}
|
||||
}
|
||||
|
||||
await this._webview!.initializeMarkup(requests.map(request => ({
|
||||
mime: 'text/markdown',
|
||||
cellId: request[0].id,
|
||||
cellHandle: request[0].handle,
|
||||
content: request[0].getText(),
|
||||
offset: request[1],
|
||||
visible: false,
|
||||
})));
|
||||
await this._webview!.initializeMarkup(requests.map(([model, offset]) => this.createMarkupCellInitialization(model, offset)));
|
||||
} else {
|
||||
const initRequests = viewModel.viewCells.filter(cell => cell.cellKind === CellKind.Markup).slice(0, 5).map(cell => ({
|
||||
cellId: cell.id, cellHandle: cell.handle, content: cell.getText(), offset: -10000, visible: false, mime: 'text/markdown',
|
||||
}));
|
||||
const initRequests = viewModel.viewCells
|
||||
.filter(cell => cell.cellKind === CellKind.Markup)
|
||||
.slice(0, 5)
|
||||
.map(cell => this.createMarkupCellInitialization(cell, -10000));
|
||||
|
||||
await this._webview!.initializeMarkup(initRequests);
|
||||
|
||||
// no cached view state so we are rendering the first viewport
|
||||
@@ -1420,6 +1416,17 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
}
|
||||
}
|
||||
|
||||
private createMarkupCellInitialization(model: ICellViewModel, offset: number): IMarkupCellInitialization {
|
||||
return ({
|
||||
mime: model.mime,
|
||||
cellId: model.id,
|
||||
cellHandle: model.handle,
|
||||
content: model.getText(),
|
||||
offset: offset,
|
||||
visible: false,
|
||||
});
|
||||
}
|
||||
|
||||
restoreListViewState(viewState: INotebookEditorViewState | undefined): void {
|
||||
if (viewState?.scrollPosition !== undefined) {
|
||||
this._list.scrollTop = viewState!.scrollPosition.top;
|
||||
@@ -2264,7 +2271,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
||||
|
||||
const cellTop = this._list.getAbsoluteTopOfElement(cell);
|
||||
await this._webview.showMarkdownPreview({
|
||||
mime: 'text/markdown',
|
||||
mime: cell.mime,
|
||||
cellHandle: cell.handle,
|
||||
cellId: cell.id,
|
||||
content: cell.getText(),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { dirname } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { MarkdownRenderer } from 'vs/editor/browser/core/markdownRenderer';
|
||||
@@ -215,7 +216,7 @@ class PlainTextRendererContrib extends Disposable implements IOutputRendererCont
|
||||
}
|
||||
|
||||
getMimetypes() {
|
||||
return ['text/plain'];
|
||||
return [Mimes.text];
|
||||
}
|
||||
|
||||
constructor(
|
||||
@@ -270,7 +271,7 @@ class MdRendererContrib extends Disposable implements IOutputRendererContributio
|
||||
}
|
||||
|
||||
getMimetypes() {
|
||||
return ['text/markdown'];
|
||||
return [Mimes.markdown];
|
||||
}
|
||||
|
||||
constructor(
|
||||
|
||||
@@ -525,17 +525,12 @@ var requirejs = (function() {
|
||||
}
|
||||
case 'focus-editor':
|
||||
{
|
||||
const resolvedResult = this.resolveOutputId(data.id);
|
||||
if (resolvedResult) {
|
||||
const latestCell = this.notebookEditor.getCellByInfo(resolvedResult.cellInfo);
|
||||
if (!latestCell) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cell = this.notebookEditor.getCellById(data.cellId);
|
||||
if (cell) {
|
||||
if (data.focusNext) {
|
||||
this.notebookEditor.focusNextNotebookCell(latestCell, 'editor');
|
||||
this.notebookEditor.focusNextNotebookCell(cell, 'editor');
|
||||
} else {
|
||||
this.notebookEditor.focusNotebookCell(latestCell, 'editor');
|
||||
this.notebookEditor.focusNotebookCell(cell, 'editor');
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -812,6 +807,7 @@ var requirejs = (function() {
|
||||
this.hiddenInsetMapping.delete(request.output);
|
||||
|
||||
return {
|
||||
cellId: request.cell.id,
|
||||
outputId: id,
|
||||
cellTop: request.cellTop,
|
||||
outputOffset: request.outputOffset,
|
||||
@@ -826,7 +822,7 @@ var requirejs = (function() {
|
||||
this._sendMessageToWebview({
|
||||
type: 'view-scroll',
|
||||
widgets: widgets,
|
||||
markdownPreviews,
|
||||
markupCells: markdownPreviews,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { Delayer } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
@@ -49,8 +47,8 @@ export class CellDragAndDropController extends Disposable {
|
||||
|
||||
this.listInsertionIndicator = DOM.append(insertionIndicatorContainer, $('.cell-list-insertion-indicator'));
|
||||
|
||||
this._register(domEvent(document.body, DOM.EventType.DRAG_START, true)(this.onGlobalDragStart.bind(this)));
|
||||
this._register(domEvent(document.body, DOM.EventType.DRAG_END, true)(this.onGlobalDragEnd.bind(this)));
|
||||
this._register(DOM.addDisposableListener(document.body, DOM.EventType.DRAG_START, this.onGlobalDragStart.bind(this), true));
|
||||
this._register(DOM.addDisposableListener(document.body, DOM.EventType.DRAG_END, this.onGlobalDragEnd.bind(this), true));
|
||||
|
||||
const addCellDragListener = (eventType: string, handler: (e: CellDragEvent) => void) => {
|
||||
this._register(DOM.addDisposableListener(
|
||||
@@ -300,7 +298,7 @@ export class CellDragAndDropController extends Disposable {
|
||||
const container = templateData.container;
|
||||
dragHandle.setAttribute('draggable', 'true');
|
||||
|
||||
templateData.disposables.add(domEvent(dragHandle, DOM.EventType.DRAG_END)(() => {
|
||||
templateData.disposables.add(DOM.addDisposableListener(dragHandle, DOM.EventType.DRAG_END, () => {
|
||||
if (!this.notebookEditor.notebookOptions.getLayoutConfiguration().dragAndDropEnabled) {
|
||||
return;
|
||||
}
|
||||
@@ -310,7 +308,7 @@ export class CellDragAndDropController extends Disposable {
|
||||
this.dragCleanup();
|
||||
}));
|
||||
|
||||
templateData.disposables.add(domEvent(dragHandle, DOM.EventType.DRAG_START)(event => {
|
||||
templateData.disposables.add(DOM.addDisposableListener(dragHandle, DOM.EventType.DRAG_START, event => {
|
||||
if (!event.dataTransfer) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { getPixelRatio, getZoomLevel } from 'vs/base/browser/browser';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import * as aria from 'vs/base/browser/ui/aria/aria';
|
||||
import { renderIcon } from 'vs/base/browser/ui/iconLabel/iconLabels';
|
||||
import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
@@ -261,7 +260,7 @@ abstract class AbstractCellRenderer {
|
||||
}
|
||||
|
||||
protected addExpandListener(templateData: BaseCellRenderTemplate): void {
|
||||
templateData.disposables.add(domEvent(templateData.expandButton, DOM.EventType.CLICK)(() => {
|
||||
templateData.disposables.add(DOM.addDisposableListener(templateData.expandButton, DOM.EventType.CLICK, () => {
|
||||
if (!templateData.currentRenderedCell) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export interface IScrollAckMessage extends BaseToWebviewMessage {
|
||||
|
||||
export interface IBlurOutputMessage extends BaseToWebviewMessage {
|
||||
readonly type: 'focus-editor';
|
||||
readonly id: string;
|
||||
readonly cellId: string;
|
||||
readonly focusNext?: boolean;
|
||||
}
|
||||
|
||||
@@ -174,6 +174,7 @@ export interface ICreationRequestMessage {
|
||||
}
|
||||
|
||||
export interface IContentWidgetTopRequest {
|
||||
readonly cellId: string;
|
||||
readonly outputId: string;
|
||||
readonly cellTop: number;
|
||||
readonly outputOffset: number;
|
||||
@@ -183,7 +184,7 @@ export interface IContentWidgetTopRequest {
|
||||
export interface IViewScrollTopRequestMessage {
|
||||
readonly type: 'view-scroll';
|
||||
readonly widgets: IContentWidgetTopRequest[];
|
||||
readonly markdownPreviews: { id: string; top: number; }[];
|
||||
readonly markupCells: { id: string; top: number; }[];
|
||||
}
|
||||
|
||||
export interface IScrollRequestMessage {
|
||||
|
||||
@@ -320,12 +320,12 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
}
|
||||
}
|
||||
|
||||
function createFocusSink(cellId: string, outputId: string, focusNext?: boolean) {
|
||||
function createFocusSink(cellId: string, focusNext?: boolean) {
|
||||
const element = document.createElement('div');
|
||||
element.tabIndex = 0;
|
||||
element.addEventListener('focus', () => {
|
||||
postNotebookMessage<webviewMessages.IBlurOutputMessage>('focus-editor', {
|
||||
id: outputId,
|
||||
cellId: cellId,
|
||||
focusNext
|
||||
});
|
||||
});
|
||||
@@ -357,7 +357,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
return false;
|
||||
}
|
||||
|
||||
class FocusTracker {
|
||||
class OutputFocusTracker {
|
||||
private _outputId: string;
|
||||
private _hasFocus: boolean = false;
|
||||
private _loosingFocus: boolean = false;
|
||||
@@ -405,14 +405,14 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
}
|
||||
}
|
||||
|
||||
const focusTrackers = new Map<string, FocusTracker>();
|
||||
const outputFocusTrackers = new Map<string, OutputFocusTracker>();
|
||||
|
||||
function addFocusTracker(element: HTMLElement, outputId: string): void {
|
||||
if (focusTrackers.has(outputId)) {
|
||||
focusTrackers.get(outputId)?.dispose();
|
||||
function addOutputFocusTracker(element: HTMLElement, outputId: string): void {
|
||||
if (outputFocusTrackers.has(outputId)) {
|
||||
outputFocusTrackers.get(outputId)?.dispose();
|
||||
}
|
||||
|
||||
focusTrackers.set(outputId, new FocusTracker(element, outputId));
|
||||
outputFocusTrackers.set(outputId, new OutputFocusTracker(element, outputId));
|
||||
}
|
||||
|
||||
function createEmitter<T>(listenerChange: (listeners: Set<Listener<T>>) => void = () => undefined): EmitterLike<T> {
|
||||
@@ -510,44 +510,46 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
|
||||
switch (event.data.type) {
|
||||
case 'initializeMarkup':
|
||||
await notebookDocument.ensureMarkupCells(event.data.cells);
|
||||
await viewModel.ensureMarkupCells(event.data.cells);
|
||||
dimensionUpdater.updateImmediately();
|
||||
postNotebookMessage('initializedMarkup', {});
|
||||
break;
|
||||
|
||||
case 'createMarkupCell':
|
||||
notebookDocument.ensureMarkupCells([event.data.cell]);
|
||||
viewModel.ensureMarkupCells([event.data.cell]);
|
||||
break;
|
||||
|
||||
case 'showMarkupCell':
|
||||
notebookDocument.showMarkupCell(event.data.id, event.data.top, event.data.content);
|
||||
viewModel.showMarkupCell(event.data.id, event.data.top, event.data.content);
|
||||
break;
|
||||
|
||||
case 'hideMarkupCells':
|
||||
for (const id of event.data.ids) {
|
||||
notebookDocument.hideMarkupCell(id);
|
||||
viewModel.hideMarkupCell(id);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'unhideMarkupCells':
|
||||
for (const id of event.data.ids) {
|
||||
notebookDocument.unhideMarkupCell(id);
|
||||
viewModel.unhideMarkupCell(id);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'deleteMarkupCell':
|
||||
for (const id of event.data.ids) {
|
||||
notebookDocument.deleteMarkupCell(id);
|
||||
viewModel.deleteMarkupCell(id);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'updateSelectedMarkupCells':
|
||||
notebookDocument.updateSelectedCells(event.data.selectedCellIds);
|
||||
viewModel.updateSelectedCells(event.data.selectedCellIds);
|
||||
break;
|
||||
|
||||
case 'html': {
|
||||
const data = event.data;
|
||||
outputs.enqueue(event.data.outputId, async (state) => {
|
||||
const outputId = data.outputId;
|
||||
|
||||
outputRunner.enqueue(event.data.outputId, async (state) => {
|
||||
const preloadsAndErrors = await Promise.all<unknown>([
|
||||
data.rendererId ? renderers.load(data.rendererId) : undefined,
|
||||
...data.requiredPreloads.map(p => kernelPreloads.waitFor(p.uri)),
|
||||
@@ -557,48 +559,9 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
return;
|
||||
}
|
||||
|
||||
let cellOutputContainer = document.getElementById(data.cellId);
|
||||
const outputId = data.outputId;
|
||||
if (!cellOutputContainer) {
|
||||
const container = document.getElementById('container')!;
|
||||
const cellOutput = viewModel.ensureOutputCell(data.cellId, data.cellTop);
|
||||
const outputNode = cellOutput.createOutputNode(outputId, data.outputOffset, data.left);
|
||||
|
||||
const upperWrapperElement = createFocusSink(data.cellId, outputId);
|
||||
container.appendChild(upperWrapperElement);
|
||||
|
||||
const newElement = document.createElement('div');
|
||||
|
||||
newElement.id = data.cellId;
|
||||
newElement.classList.add('cell_container');
|
||||
|
||||
container.appendChild(newElement);
|
||||
cellOutputContainer = newElement;
|
||||
|
||||
const lowerWrapperElement = createFocusSink(data.cellId, outputId, true);
|
||||
container.appendChild(lowerWrapperElement);
|
||||
}
|
||||
|
||||
cellOutputContainer.style.position = 'absolute';
|
||||
cellOutputContainer.style.top = data.cellTop + 'px';
|
||||
|
||||
const outputContainer = document.createElement('div');
|
||||
outputContainer.classList.add('output_container');
|
||||
outputContainer.style.position = 'absolute';
|
||||
outputContainer.style.overflow = 'hidden';
|
||||
outputContainer.style.maxHeight = '0px';
|
||||
outputContainer.style.top = `${data.outputOffset}px`;
|
||||
|
||||
const outputNode = document.createElement('div');
|
||||
outputNode.classList.add('output');
|
||||
outputNode.style.position = 'absolute';
|
||||
outputNode.style.top = `0px`;
|
||||
outputNode.style.left = data.left + 'px';
|
||||
// outputNode.style.width = 'calc(100% - ' + data.left + 'px)';
|
||||
// outputNode.style.minHeight = '32px';
|
||||
outputNode.style.padding = '0px';
|
||||
outputNode.id = outputId;
|
||||
|
||||
addMouseoverListeners(outputNode, outputId);
|
||||
addFocusTracker(outputNode, outputId);
|
||||
const content = data.content;
|
||||
if (content.type === RenderOutputType.Html) {
|
||||
const trustedHtml = ttPolicy?.createHTML(content.htmlContent) ?? content.htmlContent;
|
||||
@@ -634,8 +597,6 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
}
|
||||
}
|
||||
|
||||
cellOutputContainer.appendChild(outputContainer);
|
||||
outputContainer.appendChild(outputNode);
|
||||
resizeObserver.observe(outputNode, outputId, true);
|
||||
|
||||
if (content.type === RenderOutputType.Html) {
|
||||
@@ -661,7 +622,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
}
|
||||
|
||||
// don't hide until after this step so that the height is right
|
||||
cellOutputContainer.style.visibility = data.initiallyHidden ? 'hidden' : 'visible';
|
||||
cellOutput.element.style.visibility = data.initiallyHidden ? 'hidden' : 'visible';
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -670,84 +631,46 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
// const date = new Date();
|
||||
// console.log('----- will scroll ---- ', date.getMinutes() + ':' + date.getSeconds() + ':' + date.getMilliseconds());
|
||||
|
||||
for (const request of event.data.widgets) {
|
||||
const widget = document.getElementById(request.outputId);
|
||||
if (widget) {
|
||||
widget.parentElement!.parentElement!.style.top = `${request.cellTop}px`;
|
||||
widget.parentElement!.style.top = `${request.outputOffset}px`;
|
||||
if (request.forceDisplay) {
|
||||
widget.parentElement!.parentElement!.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const cell of event.data.markdownPreviews) {
|
||||
const container = document.getElementById(cell.id);
|
||||
if (container) {
|
||||
container.style.top = `${cell.top}px`;
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.updateOutputsScroll(event.data.widgets);
|
||||
viewModel.updateMarkupScrolls(event.data.markupCells);
|
||||
break;
|
||||
}
|
||||
case 'clear':
|
||||
renderers.clearAll();
|
||||
viewModel.clearAll();
|
||||
document.getElementById('container')!.innerText = '';
|
||||
|
||||
focusTrackers.forEach(ft => {
|
||||
outputFocusTrackers.forEach(ft => {
|
||||
ft.dispose();
|
||||
});
|
||||
focusTrackers.clear();
|
||||
outputFocusTrackers.clear();
|
||||
break;
|
||||
|
||||
case 'clearOutput': {
|
||||
const output = document.getElementById(event.data.outputId);
|
||||
const { rendererId, outputId } = event.data;
|
||||
|
||||
outputs.cancelOutput(outputId);
|
||||
if (output && output.parentNode) {
|
||||
if (rendererId) {
|
||||
renderers.clearOutput(rendererId, outputId);
|
||||
}
|
||||
output.parentNode.removeChild(output);
|
||||
}
|
||||
|
||||
const { cellId, rendererId, outputId } = event.data;
|
||||
outputRunner.cancelOutput(outputId);
|
||||
viewModel.clearOutput(cellId, outputId, rendererId);
|
||||
break;
|
||||
}
|
||||
case 'hideOutput': {
|
||||
const { outputId } = event.data;
|
||||
outputs.enqueue(event.data.outputId, () => {
|
||||
const container = document.getElementById(outputId)?.parentElement?.parentElement;
|
||||
if (container) {
|
||||
container.style.visibility = 'hidden';
|
||||
}
|
||||
const { cellId, outputId } = event.data;
|
||||
outputRunner.enqueue(outputId, () => {
|
||||
viewModel.hideOutput(cellId);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'showOutput': {
|
||||
const { outputId, cellTop: top } = event.data;
|
||||
outputs.enqueue(event.data.outputId, () => {
|
||||
const output = document.getElementById(outputId);
|
||||
if (output) {
|
||||
output.parentElement!.parentElement!.style.visibility = 'visible';
|
||||
output.parentElement!.parentElement!.style.top = top + 'px';
|
||||
|
||||
dimensionUpdater.update(outputId, output.clientHeight, {
|
||||
isOutput: true,
|
||||
});
|
||||
}
|
||||
const { outputId, cellTop, cellId } = event.data;
|
||||
outputRunner.enqueue(outputId, () => {
|
||||
viewModel.showOutput(cellId, outputId, cellTop);
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'ack-dimension':
|
||||
{
|
||||
const { outputId, height } = event.data;
|
||||
const output = document.getElementById(outputId);
|
||||
if (output) {
|
||||
output.parentElement!.style.maxHeight = `${height}px`;
|
||||
output.parentElement!.style.height = `${height}px`;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ack-dimension': {
|
||||
const { cellId, outputId, height } = event.data;
|
||||
viewModel.updateOutputHeight(cellId, outputId, height);
|
||||
break;
|
||||
}
|
||||
case 'preload':
|
||||
const resources = event.data.resources;
|
||||
for (const { uri, originalUri } of resources) {
|
||||
@@ -790,12 +713,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
break;
|
||||
case 'notebookOptions':
|
||||
currentOptions = event.data.options;
|
||||
|
||||
// Update markdown previews
|
||||
for (const markdownContainer of document.querySelectorAll('.preview')) {
|
||||
setMarkupContainerDraggable(markdownContainer, currentOptions.dragAndDropEnabled);
|
||||
}
|
||||
|
||||
viewModel.toggleDragDropEnabled(currentOptions.dragAndDropEnabled);
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -905,8 +823,9 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
}
|
||||
};
|
||||
|
||||
const outputs = new class {
|
||||
private outputs = new Map<string, { cancelled: boolean; queue: Promise<unknown> }>();
|
||||
const outputRunner = new class {
|
||||
private readonly outputs = new Map<string, { cancelled: boolean; queue: Promise<unknown> }>();
|
||||
|
||||
/**
|
||||
* Pushes the action onto the list of actions for the given output ID,
|
||||
* ensuring that it's run in-order.
|
||||
@@ -973,14 +892,14 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
|
||||
|
||||
public clearAll() {
|
||||
outputs.cancelAll();
|
||||
outputRunner.cancelAll();
|
||||
for (const renderer of this._renderers.values()) {
|
||||
renderer.api?.disposeOutputItem?.();
|
||||
}
|
||||
}
|
||||
|
||||
public clearOutput(rendererId: string, outputId: string) {
|
||||
outputs.cancelOutput(outputId);
|
||||
outputRunner.cancelOutput(outputId);
|
||||
this._renderers.get(rendererId)?.api?.disposeOutputItem?.(outputId);
|
||||
}
|
||||
|
||||
@@ -1001,9 +920,10 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
let hasPostedRenderedMathTelemetry = false;
|
||||
const unsupportedKatexTermsRegex = /(\\(?:abovewithdelims|array|Arrowvert|arrowvert|atopwithdelims|bbox|bracevert|buildrel|cancelto|cases|class|cssId|ddddot|dddot|DeclareMathOperator|definecolor|displaylines|enclose|eqalign|eqalignno|eqref|hfil|hfill|idotsint|iiiint|label|leftarrowtail|leftroot|leqalignno|lower|mathtip|matrix|mbox|mit|mmlToken|moveleft|moveright|mspace|newenvironment|Newextarrow|notag|oldstyle|overparen|overwithdelims|pmatrix|raise|ref|renewenvironment|require|root|Rule|scr|shoveleft|shoveright|sideset|skew|Space|strut|style|texttip|Tiny|toggle|underparen|unicode|uproot)\b)/gi;
|
||||
|
||||
const notebookDocument = new class {
|
||||
const viewModel = new class ViewModel {
|
||||
|
||||
private readonly _markupCells = new Map<string, MarkupCell>();
|
||||
private readonly _outputCells = new Map<string, OutputCell>();
|
||||
|
||||
private async createMarkupCell(init: webviewMessages.IMarkupCellInitialization, top: number): Promise<MarkupCell> {
|
||||
const existing = this._markupCells.get(init.cellId);
|
||||
@@ -1012,11 +932,11 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
return existing;
|
||||
}
|
||||
|
||||
const markdownCell = new MarkupCell(init.cellId, init.mime, init.content, top);
|
||||
this._markupCells.set(init.cellId, markdownCell);
|
||||
const cell = new MarkupCell(init.cellId, init.mime, init.content, top);
|
||||
this._markupCells.set(init.cellId, cell);
|
||||
|
||||
await markdownCell.ready;
|
||||
return markdownCell;
|
||||
await cell.ready;
|
||||
return cell;
|
||||
}
|
||||
|
||||
public async ensureMarkupCells(update: readonly webviewMessages.IMarkupCellInitialization[]): Promise<void> {
|
||||
@@ -1074,13 +994,71 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
cell.setSelected(selectedCellSet.has(cell.id));
|
||||
}
|
||||
}
|
||||
|
||||
public toggleDragDropEnabled(dragAndDropEnabled: boolean) {
|
||||
for (const cell of this._markupCells.values()) {
|
||||
cell.toggleDragDropEnabled(dragAndDropEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
public updateMarkupScrolls(markupCells: { id: string; top: number; }[]) {
|
||||
for (const { id, top } of markupCells) {
|
||||
const cell = this._markupCells.get(id);
|
||||
if (cell) {
|
||||
cell.element.style.top = `${top}px`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public clearAll() {
|
||||
this._markupCells.clear();
|
||||
this._outputCells.clear();
|
||||
}
|
||||
|
||||
public ensureOutputCell(cellId: string, cellTop: number): OutputCell {
|
||||
let cell = this._outputCells.get(cellId);
|
||||
if (!cell) {
|
||||
cell = new OutputCell(cellId);
|
||||
this._outputCells.set(cellId, cell);
|
||||
}
|
||||
|
||||
cell.element.style.top = cellTop + 'px';
|
||||
return cell;
|
||||
}
|
||||
|
||||
public clearOutput(cellId: string, outputId: string, rendererId: string | undefined) {
|
||||
const cell = this._outputCells.get(cellId);
|
||||
cell?.clearOutput(outputId, rendererId);
|
||||
}
|
||||
|
||||
public showOutput(cellId: string, outputId: string, top: number) {
|
||||
const cell = this._outputCells.get(cellId);
|
||||
cell?.show(outputId, top);
|
||||
}
|
||||
|
||||
public hideOutput(cellId: string) {
|
||||
const cell = this._outputCells.get(cellId);
|
||||
cell?.hide();
|
||||
}
|
||||
|
||||
public updateOutputHeight(cellId: string, outputId: string, height: number) {
|
||||
const cell = this._outputCells.get(cellId);
|
||||
cell?.updateOutputHeight(outputId, height);
|
||||
}
|
||||
|
||||
public updateOutputsScroll(updates: webviewMessages.IContentWidgetTopRequest[]) {
|
||||
for (const request of updates) {
|
||||
const cell = this._outputCells.get(request.cellId);
|
||||
cell?.updateScroll(request);
|
||||
}
|
||||
}
|
||||
}();
|
||||
|
||||
class MarkupCell implements IOutputItem {
|
||||
|
||||
public readonly ready: Promise<void>;
|
||||
|
||||
/// Internal field that holds markdown text
|
||||
/// Internal field that holds text content
|
||||
private _content: string;
|
||||
|
||||
constructor(id: string, mime: string, content: string, top: number) {
|
||||
@@ -1098,6 +1076,7 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
this.element.classList.add('preview');
|
||||
this.element.style.position = 'absolute';
|
||||
this.element.style.top = top + 'px';
|
||||
this.toggleDragDropEnabled(currentOptions.dragAndDropEnabled);
|
||||
root.appendChild(this.element);
|
||||
|
||||
this.addEventListeners();
|
||||
@@ -1155,18 +1134,16 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
postNotebookMessage<webviewMessages.IMouseLeaveMarkupCellMessage>('mouseLeaveMarkupCell', { cellId: this.id });
|
||||
});
|
||||
|
||||
setMarkupContainerDraggable(this.element, currentOptions.dragAndDropEnabled);
|
||||
|
||||
this.element.addEventListener('dragstart', e => {
|
||||
markdownPreviewDragManager.startDrag(e, this.id);
|
||||
markupCellDragManager.startDrag(e, this.id);
|
||||
});
|
||||
|
||||
this.element.addEventListener('drag', e => {
|
||||
markdownPreviewDragManager.updateDrag(e, this.id);
|
||||
markupCellDragManager.updateDrag(e, this.id);
|
||||
});
|
||||
|
||||
this.element.addEventListener('dragend', e => {
|
||||
markdownPreviewDragManager.endDrag(e, this.id);
|
||||
markupCellDragManager.endDrag(e, this.id);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1223,6 +1200,125 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
public setSelected(selected: boolean) {
|
||||
this.element.classList.toggle('selected', selected);
|
||||
}
|
||||
|
||||
public toggleDragDropEnabled(enabled: boolean) {
|
||||
if (enabled) {
|
||||
this.element.classList.add('draggable');
|
||||
this.element.setAttribute('draggable', 'true');
|
||||
} else {
|
||||
this.element.classList.remove('draggable');
|
||||
this.element.removeAttribute('draggable');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class OutputCell {
|
||||
|
||||
public readonly element: HTMLElement;
|
||||
|
||||
public readonly outputElements = new Map</*outputId*/ string, HTMLElement>();
|
||||
|
||||
constructor(cellId: string) {
|
||||
const container = document.getElementById('container')!;
|
||||
|
||||
const upperWrapperElement = createFocusSink(cellId);
|
||||
container.appendChild(upperWrapperElement);
|
||||
|
||||
this.element = document.createElement('div');
|
||||
this.element.style.position = 'absolute';
|
||||
|
||||
this.element.id = cellId;
|
||||
this.element.classList.add('cell_container');
|
||||
|
||||
container.appendChild(this.element);
|
||||
this.element = this.element;
|
||||
|
||||
const lowerWrapperElement = createFocusSink(cellId, true);
|
||||
container.appendChild(lowerWrapperElement);
|
||||
}
|
||||
|
||||
public createOutputNode(outputId: string, outputOffset: number, left: number): HTMLElement {
|
||||
let outputContainer = this.outputElements.get(outputId);
|
||||
if (!outputContainer) {
|
||||
outputContainer = document.createElement('div');
|
||||
outputContainer.classList.add('output_container');
|
||||
outputContainer.style.position = 'absolute';
|
||||
outputContainer.style.overflow = 'hidden';
|
||||
this.element.appendChild(outputContainer);
|
||||
this.outputElements.set(outputId, outputContainer);
|
||||
}
|
||||
outputContainer.innerText = '';
|
||||
outputContainer.style.maxHeight = '0px';
|
||||
outputContainer.style.top = `${outputOffset}px`;
|
||||
|
||||
const outputNode = document.createElement('div');
|
||||
outputNode.id = outputId;
|
||||
outputNode.classList.add('output');
|
||||
outputNode.style.position = 'absolute';
|
||||
outputNode.style.top = `0px`;
|
||||
outputNode.style.left = left + 'px';
|
||||
outputNode.style.padding = '0px';
|
||||
outputContainer.appendChild(outputNode);
|
||||
|
||||
addMouseoverListeners(outputNode, outputId);
|
||||
addOutputFocusTracker(outputNode, outputId);
|
||||
|
||||
return outputNode;
|
||||
}
|
||||
|
||||
public clearOutput(outputId: string, rendererId: string | undefined) {
|
||||
const outputContainer = this.outputElements.get(outputId);
|
||||
if (!outputContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rendererId) {
|
||||
renderers.clearOutput(rendererId, outputId);
|
||||
}
|
||||
outputContainer.remove();
|
||||
this.outputElements.delete(outputId);
|
||||
}
|
||||
|
||||
public show(outputId: string, top: number) {
|
||||
const outputContainer = this.outputElements.get(outputId);
|
||||
if (!outputContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.element.style.visibility = 'visible';
|
||||
this.element.style.top = `${top}px`;
|
||||
|
||||
dimensionUpdater.update(outputId, outputContainer.clientHeight, {
|
||||
isOutput: true,
|
||||
});
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this.element.style.visibility = 'hidden';
|
||||
}
|
||||
|
||||
public updateOutputHeight(outputId: string, height: number) {
|
||||
const outputContainer = this.outputElements.get(outputId);
|
||||
if (!outputContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
outputContainer.style.maxHeight = `${height}px`;
|
||||
outputContainer.style.height = `${height}px`;
|
||||
}
|
||||
|
||||
public updateScroll(request: webviewMessages.IContentWidgetTopRequest) {
|
||||
this.element.style.top = `${request.cellTop}px`;
|
||||
|
||||
const outputContainer = this.outputElements.get(request.outputId);
|
||||
if (outputContainer) {
|
||||
outputContainer.style.top = `${request.outputOffset}px`;
|
||||
}
|
||||
|
||||
if (request.forceDisplay) {
|
||||
this.element.style.visibility = 'visible';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vscode.postMessage({
|
||||
@@ -1230,16 +1326,6 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
type: 'initialized'
|
||||
});
|
||||
|
||||
function setMarkupContainerDraggable(element: Element, isDraggable: boolean) {
|
||||
if (isDraggable) {
|
||||
element.classList.add('draggable');
|
||||
element.setAttribute('draggable', 'true');
|
||||
} else {
|
||||
element.classList.remove('draggable');
|
||||
element.removeAttribute('draggable');
|
||||
}
|
||||
}
|
||||
|
||||
function postNotebookMessage<T extends webviewMessages.FromWebviewMessage>(
|
||||
type: T['type'],
|
||||
properties: Omit<T, '__vscode_notebook_message' | 'type'>
|
||||
@@ -1251,13 +1337,13 @@ async function webviewPreloads(style: PreloadStyles, options: PreloadOptions, re
|
||||
});
|
||||
}
|
||||
|
||||
const markdownPreviewDragManager = new class MarkdownPreviewDragManager {
|
||||
const markupCellDragManager = new class MarkupCellDragManager {
|
||||
|
||||
private currentDrag: { cellId: string, clientY: number } | undefined;
|
||||
|
||||
constructor() {
|
||||
document.addEventListener('dragover', e => {
|
||||
// Allow dropping dragged markdown cells
|
||||
// Allow dropping dragged markup cells
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/mode
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IResolvedTextEditorModel, ITextModelService } from 'vs/editor/common/services/resolverService';
|
||||
import { ViewContext } from 'vs/workbench/contrib/notebook/browser/viewModel/viewContext';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
export abstract class BaseCellViewModel extends Disposable {
|
||||
|
||||
@@ -46,6 +47,16 @@ export abstract class BaseCellViewModel extends Disposable {
|
||||
return this.model.language;
|
||||
}
|
||||
|
||||
get mime(): string {
|
||||
switch (this.language) {
|
||||
case 'markdown':
|
||||
return Mimes.markdown;
|
||||
|
||||
default:
|
||||
return Mimes.text;
|
||||
}
|
||||
}
|
||||
|
||||
abstract cellKind: CellKind;
|
||||
|
||||
private _editState: CellEditState = CellEditState.Preview;
|
||||
|
||||
@@ -7,6 +7,7 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { IDiffResult, ISequence } from 'vs/base/common/diff/diff';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { basename } from 'vs/base/common/path';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
@@ -34,16 +35,16 @@ export const NOTEBOOK_DISPLAY_ORDER = [
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
];
|
||||
|
||||
export const ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER = [
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/json',
|
||||
'text/plain',
|
||||
Mimes.text,
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'image/png',
|
||||
@@ -586,8 +587,8 @@ const _mimeTypeInfo = new Map<string, MimeTypeInfo>([
|
||||
['image/git', { alwaysSecure: true, supportedByCore: true }],
|
||||
['image/svg+xml', { supportedByCore: true }],
|
||||
['application/json', { alwaysSecure: true, supportedByCore: true }],
|
||||
['text/markdown', { alwaysSecure: true, supportedByCore: true }],
|
||||
['text/plain', { alwaysSecure: true, supportedByCore: true }],
|
||||
[Mimes.markdown, { alwaysSecure: true, supportedByCore: true }],
|
||||
[Mimes.text, { alwaysSecure: true, supportedByCore: true }],
|
||||
['text/html', { supportedByCore: true }],
|
||||
['text/x-javascript', { alwaysSecure: true, supportedByCore: true }], // secure because rendered as text, not executed
|
||||
['application/vnd.code.notebook.error', { alwaysSecure: true, supportedByCore: true }],
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { NOTEBOOK_DISPLAY_ORDER, sortMimeTypes, CellKind, diff, CellUri, NotebookWorkingCopyTypeIdentifier } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { cellRangesToIndexes, cellIndexesToRanges } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { TestCell, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { CellKind, CellUri, diff, NotebookWorkingCopyTypeIdentifier, NOTEBOOK_DISPLAY_ORDER, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { cellIndexesToRanges, cellRangesToIndexes } from 'vs/workbench/contrib/notebook/common/notebookRange';
|
||||
import { setupInstantiationService, TestCell } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
|
||||
suite('NotebookCommon', () => {
|
||||
const instantiationService = setupInstantiationService();
|
||||
@@ -23,30 +24,30 @@ suite('NotebookCommon', () => {
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
], [], defaultDisplayOrder),
|
||||
[
|
||||
'application/json',
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
]
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(sortMimeTypes(
|
||||
[
|
||||
'application/json',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'text/plain',
|
||||
Mimes.text,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'image/svg+xml'
|
||||
@@ -56,18 +57,18 @@ suite('NotebookCommon', () => {
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
]
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(sortMimeTypes(
|
||||
[
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/json',
|
||||
'text/plain',
|
||||
Mimes.text,
|
||||
'image/jpeg',
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
@@ -79,10 +80,10 @@ suite('NotebookCommon', () => {
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -97,22 +98,22 @@ suite('NotebookCommon', () => {
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
],
|
||||
[
|
||||
'image/png',
|
||||
'text/plain',
|
||||
'text/markdown',
|
||||
Mimes.text,
|
||||
Mimes.markdown,
|
||||
'text/html',
|
||||
'application/json'
|
||||
], defaultDisplayOrder),
|
||||
[
|
||||
'image/png',
|
||||
'text/plain',
|
||||
'text/markdown',
|
||||
Mimes.text,
|
||||
Mimes.markdown,
|
||||
'text/html',
|
||||
'application/json',
|
||||
'application/javascript',
|
||||
@@ -123,9 +124,9 @@ suite('NotebookCommon', () => {
|
||||
|
||||
assert.deepStrictEqual(sortMimeTypes(
|
||||
[
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/json',
|
||||
'text/plain',
|
||||
Mimes.text,
|
||||
'application/javascript',
|
||||
'text/html',
|
||||
'image/svg+xml',
|
||||
@@ -136,18 +137,18 @@ suite('NotebookCommon', () => {
|
||||
'application/json',
|
||||
'text/html',
|
||||
'text/html',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/json'
|
||||
], defaultDisplayOrder),
|
||||
[
|
||||
'application/json',
|
||||
'text/html',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'application/javascript',
|
||||
'image/svg+xml',
|
||||
'image/png',
|
||||
'image/jpeg',
|
||||
'text/plain'
|
||||
Mimes.text
|
||||
]
|
||||
);
|
||||
});
|
||||
@@ -165,7 +166,7 @@ suite('NotebookCommon', () => {
|
||||
'text/html'
|
||||
],
|
||||
[
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'text/html',
|
||||
'application/json'
|
||||
], defaultDisplayOrder),
|
||||
@@ -189,7 +190,7 @@ suite('NotebookCommon', () => {
|
||||
],
|
||||
[
|
||||
'application/vnd-vega*',
|
||||
'text/markdown',
|
||||
Mimes.markdown,
|
||||
'text/html',
|
||||
'application/json'
|
||||
], defaultDisplayOrder),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { LcsDiff } from 'vs/base/common/diff/diff';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { NotebookDiffEditorEventDispatcher } from 'vs/workbench/contrib/notebook/browser/diff/eventDispatcher';
|
||||
import { NotebookTextDiffEditor } from 'vs/workbench/contrib/notebook/browser/diff/notebookTextDiffEditor';
|
||||
import { CellKind, CellSequence } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
@@ -14,9 +15,9 @@ suite('NotebookCommon', () => {
|
||||
|
||||
test('diff different source', async () => {
|
||||
await withTestNotebookDiffModel([
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
], [
|
||||
['y', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
['y', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
], (model, accessor) => {
|
||||
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
|
||||
const diffResult = diff.ComputeDiff(false);
|
||||
@@ -44,10 +45,10 @@ suite('NotebookCommon', () => {
|
||||
|
||||
test('diff different output', async () => {
|
||||
await withTestNotebookDiffModel([
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([5]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
['', 'javascript', CellKind.Code, [], {}]
|
||||
], [
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someOtherId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 3 }],
|
||||
['', 'javascript', CellKind.Code, [], {}]
|
||||
], (model, accessor) => {
|
||||
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
|
||||
@@ -145,12 +146,12 @@ suite('NotebookCommon', () => {
|
||||
|
||||
test('diff foo/foe', async () => {
|
||||
await withTestNotebookDiffModel([
|
||||
[['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
[['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }],
|
||||
[['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
[['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }],
|
||||
['', 'javascript', CellKind.Code, [], {}]
|
||||
], [
|
||||
[['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
[['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }],
|
||||
[['def foo(x, y):\n', ' return x * y\n', 'foo(1, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([6]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 5 }],
|
||||
[['def foe(x, y):\n', ' return x + y\n', 'foe(3, 2)'].join(''), 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([2]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 6 }],
|
||||
['', 'javascript', CellKind.Code, [], {}]
|
||||
], (model, accessor) => {
|
||||
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
|
||||
@@ -272,13 +273,13 @@ suite('NotebookCommon', () => {
|
||||
await withTestNotebookDiffModel([
|
||||
['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }],
|
||||
['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }]
|
||||
], [
|
||||
['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }],
|
||||
['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }]
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }]
|
||||
], async (model) => {
|
||||
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
|
||||
const diffResult = diff.ComputeDiff(false);
|
||||
@@ -305,18 +306,18 @@ suite('NotebookCommon', () => {
|
||||
await withTestNotebookDiffModel([
|
||||
['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }],
|
||||
['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }],
|
||||
['x = 5', 'javascript', CellKind.Code, [], {}],
|
||||
['x', 'javascript', CellKind.Code, [], {}],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], {}],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([5]) }] }], {}],
|
||||
], [
|
||||
['# Description', 'markdown', CellKind.Markup, [], { custom: { metadata: {} } }],
|
||||
['x = 3', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: true } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [], { custom: { metadata: { collapsed: false } } }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([3]) }] }], { custom: { metadata: { collapsed: false } }, executionOrder: 1 }],
|
||||
['x = 5', 'javascript', CellKind.Code, [], {}],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: 'text/plain', data: new Uint8Array([5]) }] }], {}],
|
||||
['x', 'javascript', CellKind.Code, [{ outputId: 'someId', outputs: [{ mime: Mimes.text, data: new Uint8Array([5]) }] }], {}],
|
||||
['x', 'javascript', CellKind.Code, [], {}],
|
||||
], async (model) => {
|
||||
const diff = new LcsDiff(new CellSequence(model.original.notebook), new CellSequence(model.modified.notebook));
|
||||
|
||||
@@ -20,6 +20,7 @@ import { INotebookService } from 'vs/workbench/contrib/notebook/common/notebookS
|
||||
import { mock } from 'vs/base/test/common/mock';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
suite('NotebookEditorKernelManager', () => {
|
||||
|
||||
@@ -151,6 +152,6 @@ class TestNotebookKernel implements INotebookKernel {
|
||||
}
|
||||
|
||||
constructor(opts?: { languages: string[] }) {
|
||||
this.supportedLanguages = opts?.languages ?? ['text/plain'];
|
||||
this.supportedLanguages = opts?.languages ?? [Mimes.text];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import { CellKind, NotebookData, TransientOptions } from 'vs/workbench/contrib/n
|
||||
import { setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
suite('NotebookFileWorkingCopyModel', function () {
|
||||
|
||||
@@ -35,7 +36,7 @@ suite('NotebookFileWorkingCopyModel', function () {
|
||||
const notebook = instantiationService.createInstance(NotebookTextModel,
|
||||
'notebook',
|
||||
URI.file('test'),
|
||||
[{ cellKind: CellKind.Code, language: 'foo', source: 'foo', outputs: [{ outputId: 'id', outputs: [{ mime: 'text/plain', value: 'Hello Out' }] }] }],
|
||||
[{ cellKind: CellKind.Code, language: 'foo', source: 'foo', outputs: [{ outputId: 'id', outputs: [{ mime: Mimes.text, value: 'Hello Out' }] }] }],
|
||||
{},
|
||||
{ transientCellMetadata: {}, transientDocumentMetadata: {}, transientOutputs: false }
|
||||
);
|
||||
|
||||
@@ -16,6 +16,7 @@ import { mock } from 'vs/base/test/common/mock';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
|
||||
suite('NotebookKernelService', () => {
|
||||
|
||||
@@ -176,7 +177,7 @@ class TestNotebookKernel implements INotebookKernel {
|
||||
}
|
||||
|
||||
constructor(opts?: { languages?: string[], label?: string, viewType?: string }) {
|
||||
this.supportedLanguages = opts?.languages ?? ['text/plain'];
|
||||
this.supportedLanguages = opts?.languages ?? [Mimes.text];
|
||||
this.label = opts?.label ?? this.label;
|
||||
this.viewType = opts?.viewType ?? this.viewType;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { CellKind, CellEditType, NotebookTextModelChangedEvent, SelectionStateType, ICellEditOperation } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { withTestNotebook, TestCell, setupInstantiationService } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
||||
import { CellEditType, CellKind, ICellEditOperation, NotebookTextModelChangedEvent, SelectionStateType } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { setupInstantiationService, TestCell, withTestNotebook } from 'vs/workbench/contrib/notebook/test/testNotebookEditor';
|
||||
|
||||
suite('NotebookTextModel', () => {
|
||||
|
||||
@@ -189,7 +190,7 @@ suite('NotebookTextModel', () => {
|
||||
editType: CellEditType.Output,
|
||||
outputs: [{
|
||||
outputId: 'someId',
|
||||
outputs: [{ mime: 'text/markdown', data: valueBytesFromString('_Hello_') }]
|
||||
outputs: [{ mime: Mimes.markdown, data: valueBytesFromString('_Hello_') }]
|
||||
}]
|
||||
}], true, undefined, () => undefined, undefined);
|
||||
|
||||
@@ -203,7 +204,7 @@ suite('NotebookTextModel', () => {
|
||||
append: true,
|
||||
outputs: [{
|
||||
outputId: 'someId2',
|
||||
outputs: [{ mime: 'text/markdown', data: valueBytesFromString('_Hello2_') }]
|
||||
outputs: [{ mime: Mimes.markdown, data: valueBytesFromString('_Hello2_') }]
|
||||
}]
|
||||
}], true, undefined, () => undefined, undefined);
|
||||
|
||||
@@ -219,7 +220,7 @@ suite('NotebookTextModel', () => {
|
||||
editType: CellEditType.Output,
|
||||
outputs: [{
|
||||
outputId: 'someId3',
|
||||
outputs: [{ mime: 'text/plain', data: valueBytesFromString('Last, replaced output') }]
|
||||
outputs: [{ mime: Mimes.text, data: valueBytesFromString('Last, replaced output') }]
|
||||
}]
|
||||
}], true, undefined, () => undefined, undefined);
|
||||
|
||||
@@ -247,7 +248,7 @@ suite('NotebookTextModel', () => {
|
||||
append: true,
|
||||
outputs: [{
|
||||
outputId: 'append1',
|
||||
outputs: [{ mime: 'text/markdown', data: valueBytesFromString('append 1') }]
|
||||
outputs: [{ mime: Mimes.markdown, data: valueBytesFromString('append 1') }]
|
||||
}]
|
||||
},
|
||||
{
|
||||
@@ -256,7 +257,7 @@ suite('NotebookTextModel', () => {
|
||||
append: true,
|
||||
outputs: [{
|
||||
outputId: 'append2',
|
||||
outputs: [{ mime: 'text/markdown', data: valueBytesFromString('append 2') }]
|
||||
outputs: [{ mime: Mimes.markdown, data: valueBytesFromString('append 2') }]
|
||||
}]
|
||||
}
|
||||
], true, undefined, () => undefined, undefined);
|
||||
@@ -584,7 +585,7 @@ suite('NotebookTextModel', () => {
|
||||
{
|
||||
editType: CellEditType.Output, handle: 0, append: true, outputs: [{
|
||||
outputId: 'newOutput',
|
||||
outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
outputs: [{ mime: Mimes.text, data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
}]
|
||||
}
|
||||
];
|
||||
@@ -614,7 +615,7 @@ suite('NotebookTextModel', () => {
|
||||
{
|
||||
editType: CellEditType.Output, index: 2, append: true, outputs: [{
|
||||
outputId: 'newOutput',
|
||||
outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
outputs: [{ mime: Mimes.text, data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
}]
|
||||
}
|
||||
];
|
||||
@@ -641,7 +642,7 @@ suite('NotebookTextModel', () => {
|
||||
{
|
||||
editType: CellEditType.Output, index: 1, append: true, outputs: [{
|
||||
outputId: 'newOutput',
|
||||
outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
outputs: [{ mime: Mimes.text, data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
}]
|
||||
},
|
||||
{
|
||||
@@ -650,7 +651,7 @@ suite('NotebookTextModel', () => {
|
||||
{
|
||||
editType: CellEditType.Output, index: 1, append: true, outputs: [{
|
||||
outputId: 'newOutput2',
|
||||
outputs: [{ mime: 'text/plain', data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
outputs: [{ mime: Mimes.text, data: valueBytesFromString('cba') }, { mime: 'application/foo', data: valueBytesFromString('cba') }]
|
||||
}]
|
||||
}
|
||||
];
|
||||
|
||||
@@ -314,7 +314,9 @@ class OnAutoForwardedAction extends Disposable {
|
||||
}
|
||||
|
||||
private linkMessage() {
|
||||
return nls.localize('remote.tunnelsView.notificationLink', "[See all forwarded ports](command:{0}.focus)", TunnelPanel.ID);
|
||||
return nls.localize(
|
||||
{ key: 'remote.tunnelsView.notificationLink2', comment: ['[See all forwarded ports]({0}) is a link. Only translate `See all forwarded ports`. Do not change brackets and parentheses or {0}'] },
|
||||
"[See all forwarded ports]({0})", `command:${TunnelPanel.ID}.focus`);
|
||||
}
|
||||
|
||||
private async showNotification(tunnel: RemoteTunnel) {
|
||||
|
||||
@@ -301,7 +301,11 @@ export class RemoteStatusIndicator extends Disposable implements IWorkbenchContr
|
||||
const workspaceLabel = this.getWorkspaceLabel();
|
||||
if (workspaceLabel) {
|
||||
const toolTip: IMarkdownString = {
|
||||
value: nls.localize('workspace.tooltip', "Virtual workspace on {0}\n\n[Some features](command:{1}) are not available for resources located on a virtual file system.", workspaceLabel, LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID),
|
||||
value: nls.localize(
|
||||
{ key: 'workspace.tooltip2', comment: ['{0} is a remote location name, e.g. GitHub', '[Some features]({1}) is a link. Only translate `Some features`. Do not change brackets and parentheses or {1}'] },
|
||||
"Virtual workspace on {0}\n\n[Some features]({1}) are not available for resources located on a virtual file system.",
|
||||
workspaceLabel, `command:${LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID}`
|
||||
),
|
||||
isTrusted: true
|
||||
};
|
||||
this.renderRemoteStatusIndicator(`$(remote) ${truncate(workspaceLabel, RemoteStatusIndicator.REMOTE_STATUS_LABEL_MAX_LENGTH)}`, toolTip);
|
||||
|
||||
@@ -327,7 +327,7 @@ suite('SearchModel', () => {
|
||||
}
|
||||
|
||||
function stub(arg1: any, arg2: any, arg3: any): sinon.SinonStub {
|
||||
const stub = sinon.stub(arg1, arg2, arg3);
|
||||
const stub = sinon.stub(arg1, arg2).callsFake(arg3);
|
||||
restoreStubs.push(stub);
|
||||
return stub;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-outer-container,
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-groups-container,
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group {
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group,
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-split-pane {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@@ -314,14 +315,21 @@
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
pointer-events: none;
|
||||
opacity: 0; /* hidden initially */
|
||||
transition: left 70ms ease-out, right 70ms ease-out, opacity 150ms ease-out;
|
||||
transition: left 70ms ease-out, right 70ms ease-out, top 70ms ease-out, bottom 70ms ease-out, opacity 150ms ease-out;
|
||||
}
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-drop-overlay.drop-left {
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group > .monaco-split-view2.horizontal .terminal-drop-overlay.drop-before {
|
||||
right: 50%;
|
||||
}
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-drop-overlay.drop-right {
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group > .monaco-split-view2.horizontal .terminal-drop-overlay.drop-after {
|
||||
left: 50%
|
||||
}
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group > .monaco-split-view2.vertical .terminal-drop-overlay.drop-before {
|
||||
bottom: 50%;
|
||||
}
|
||||
.monaco-workbench .pane-body.integrated-terminal .terminal-group > .monaco-split-view2.vertical .terminal-drop-overlay.drop-after {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ export interface ITerminalService {
|
||||
* Moves a terminal instance's group to the target instance group's position.
|
||||
*/
|
||||
moveGroup(source: ITerminalInstance, target: ITerminalInstance): void;
|
||||
moveInstance(source: ITerminalInstance, target: ITerminalInstance, side: 'left' | 'right'): void;
|
||||
moveInstance(source: ITerminalInstance, target: ITerminalInstance, side: 'before' | 'after'): void;
|
||||
|
||||
/**
|
||||
* Perform an action with the active terminal instance, if the terminal does
|
||||
@@ -631,7 +631,7 @@ export interface ITerminalInstance {
|
||||
|
||||
export interface IRequestAddInstanceToGroupEvent {
|
||||
uri: URI;
|
||||
side: 'left' | 'right'
|
||||
side: 'before' | 'after'
|
||||
}
|
||||
|
||||
export const enum LinuxDistro {
|
||||
|
||||
@@ -15,10 +15,10 @@ import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService
|
||||
import { EndOfLinePreference } from 'vs/editor/common/model';
|
||||
import { localize } from 'vs/nls';
|
||||
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { Action2, ICommandActionTitle, ILocalizedString, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { Action2, ICommandActionTitle, ILocalizedString, registerAction2 } from 'vs/platform/actions/common/actions';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ContextKeyAndExpr, ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
@@ -32,8 +32,9 @@ import { PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/w
|
||||
import { FindInFilesCommand, IFindInFilesArgs } from 'vs/workbench/contrib/search/browser/searchActions';
|
||||
import { Direction, IRemoteTerminalService, ITerminalInstance, ITerminalInstanceService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { TerminalQuickAccessProvider } from 'vs/workbench/contrib/terminal/browser/terminalQuickAccess';
|
||||
import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_TABS_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_ACTION_CATEGORY, TerminalCommandId, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { IRemoteTerminalAttachTarget, ITerminalConfigHelper, KEYBINDING_CONTEXT_TERMINAL_A11Y_TREE_FOCUS, KEYBINDING_CONTEXT_TERMINAL_ALT_BUFFER_ACTIVE, KEYBINDING_CONTEXT_TERMINAL_FIND_FOCUSED, KEYBINDING_CONTEXT_TERMINAL_FIND_NOT_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FIND_VISIBLE, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_TABS_FOCUS, KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, KEYBINDING_CONTEXT_TERMINAL_TEXT_SELECTED, TERMINAL_ACTION_CATEGORY, TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ITerminalContributionService } from 'vs/workbench/contrib/terminal/common/terminalExtensionPoints';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver';
|
||||
import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
@@ -342,38 +343,10 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.Focus,
|
||||
title: { value: localize('workbench.action.terminal.focus', "Focus Terminal"), original: 'Focus Terminal' },
|
||||
title: terminalStrings.focus,
|
||||
f1: true,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED,
|
||||
// This command is used to show instead of tabs when there is only a single terminal
|
||||
menu: {
|
||||
id: MenuId.ViewTitle,
|
||||
group: 'navigation',
|
||||
order: 0,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.has(`config.${TerminalSettingId.TabsEnabled}`),
|
||||
ContextKeyExpr.or(
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleTerminal'),
|
||||
ContextKeyExpr.equals('terminalCount', 1)
|
||||
),
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleTerminalOrNarrow'),
|
||||
ContextKeyExpr.or(
|
||||
ContextKeyExpr.equals('terminalCount', 1),
|
||||
ContextKeyExpr.has('isTerminalTabsNarrow')
|
||||
)
|
||||
),
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleGroup'),
|
||||
ContextKeyExpr.equals('terminalGroupCount', 1)
|
||||
),
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'always')
|
||||
)
|
||||
]),
|
||||
}
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor) {
|
||||
@@ -1339,7 +1312,7 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.Split,
|
||||
title: { value: localize('workbench.action.terminal.split', "Split Terminal"), original: 'Split Terminal' },
|
||||
title: terminalStrings.split,
|
||||
f1: true,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED,
|
||||
@@ -1361,15 +1334,6 @@ export function registerTerminalActions() {
|
||||
type: 'object'
|
||||
}
|
||||
}]
|
||||
},
|
||||
menu: {
|
||||
id: MenuId.ViewTitle,
|
||||
group: 'navigation',
|
||||
order: 2,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`)
|
||||
])
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1389,7 +1353,7 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.SplitInstance,
|
||||
title: { value: localize('workbench.action.terminal.splitInstance', "Split Terminal"), original: 'Split Terminal' },
|
||||
title: terminalStrings.split,
|
||||
f1: false,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED,
|
||||
@@ -1423,7 +1387,7 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.Unsplit,
|
||||
title: { value: localize('workbench.action.terminal.unsplit', "Unsplit Terminal"), original: 'Unsplit Terminal' },
|
||||
title: terminalStrings.unsplit,
|
||||
f1: true,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
@@ -1438,7 +1402,7 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.UnsplitInstance,
|
||||
title: { value: localize('workbench.action.terminal.unsplit', "Unsplit Terminal"), original: 'Unsplit Terminal' },
|
||||
title: terminalStrings.unsplit,
|
||||
f1: true,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
@@ -1578,16 +1542,7 @@ export function registerTerminalActions() {
|
||||
f1: true,
|
||||
category,
|
||||
precondition: ContextKeyExpr.or(KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN),
|
||||
icon: Codicon.trash,
|
||||
menu: {
|
||||
id: MenuId.ViewTitle,
|
||||
group: 'navigation',
|
||||
order: 3,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`)
|
||||
])
|
||||
}
|
||||
icon: Codicon.trash
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor) {
|
||||
@@ -1605,9 +1560,7 @@ export function registerTerminalActions() {
|
||||
constructor() {
|
||||
super({
|
||||
id: TerminalCommandId.KillInstance,
|
||||
title: {
|
||||
value: localize('workbench.action.terminal.kill.short', "Kill Terminal"), original: 'Kill Terminal'
|
||||
},
|
||||
title: terminalStrings.kill,
|
||||
f1: false,
|
||||
category,
|
||||
precondition: ContextKeyExpr.or(KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_IS_OPEN),
|
||||
@@ -1656,10 +1609,7 @@ export function registerTerminalActions() {
|
||||
});
|
||||
}
|
||||
run(accessor: ServicesAccessor) {
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => {
|
||||
t.clear();
|
||||
t.focus();
|
||||
});
|
||||
accessor.get(ITerminalService).doWithActiveInstance(t => t.clear());
|
||||
}
|
||||
});
|
||||
registerAction2(class extends Action2 {
|
||||
@@ -1684,15 +1634,7 @@ export function registerTerminalActions() {
|
||||
title: TerminalCommandId.CreateWithProfileButton,
|
||||
f1: false,
|
||||
category,
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED,
|
||||
menu: [{
|
||||
id: MenuId.ViewTitle,
|
||||
group: 'navigation',
|
||||
order: 0,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID)
|
||||
]),
|
||||
}]
|
||||
precondition: KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor) {
|
||||
|
||||
@@ -58,8 +58,10 @@ import { isMacintosh, isWindows, OperatingSystem, OS } from 'vs/base/common/plat
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { DragAndDropObserver, IDragAndDropObserverCallbacks } from 'vs/workbench/browser/dnd';
|
||||
import { containsDragType, DragAndDropObserver, IDragAndDropObserverCallbacks } from 'vs/workbench/browser/dnd';
|
||||
import { getColorClass } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
|
||||
import { IWorkbenchLayoutService, Position } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
|
||||
// How long in milliseconds should an average frame take to render for a notification to appear
|
||||
// which suggests the fallback DOM-based renderer
|
||||
@@ -832,14 +834,14 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
|
||||
|
||||
private _initDragAndDrop(container: HTMLElement) {
|
||||
this._dndObserver?.dispose();
|
||||
const dndController = new TerminalInstanceDragAndDropController(container);
|
||||
const dndController = this._instantiationService.createInstance(TerminalInstanceDragAndDropController, container);
|
||||
dndController.onDropTerminal(e => this._onRequestAddInstanceToGroup.fire(e));
|
||||
dndController.onDropFile(async path => {
|
||||
const preparedPath = await this._terminalInstanceService.preparePathForTerminalAsync(path, this.shellLaunchConfig.executable, this.title, this.shellType, this.isRemote);
|
||||
this.sendText(preparedPath, false);
|
||||
this.focus();
|
||||
});
|
||||
this._dndObserver = new DragAndDropObserver(container.parentElement!, dndController);
|
||||
this._dndObserver = new DragAndDropObserver(container, dndController);
|
||||
}
|
||||
|
||||
private async _measureRenderTime(): Promise<void> {
|
||||
@@ -1936,7 +1938,9 @@ class TerminalInstanceDragAndDropController extends Disposable implements IDragA
|
||||
get onDropTerminal(): Event<IRequestAddInstanceToGroupEvent> { return this._onDropTerminal.event; }
|
||||
|
||||
constructor(
|
||||
private readonly _container: HTMLElement
|
||||
private readonly _container: HTMLElement,
|
||||
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
|
||||
@IViewDescriptorService private readonly _viewDescriptorService: IViewDescriptorService,
|
||||
) {
|
||||
super();
|
||||
this._register(toDisposable(() => this._clearDropOverlay()));
|
||||
@@ -1950,6 +1954,10 @@ class TerminalInstanceDragAndDropController extends Disposable implements IDragA
|
||||
}
|
||||
|
||||
onDragEnter(e: DragEvent) {
|
||||
if (!containsDragType(e, DataTransfers.FILES, DataTransfers.RESOURCES, 'terminals')) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._dropOverlay) {
|
||||
this._dropOverlay = document.createElement('div');
|
||||
this._dropOverlay.classList.add('terminal-drop-overlay');
|
||||
@@ -1960,8 +1968,8 @@ class TerminalInstanceDragAndDropController extends Disposable implements IDragA
|
||||
// Dragging terminals
|
||||
if (types.includes('terminals')) {
|
||||
const side = this._getDropSide(e);
|
||||
this._dropOverlay.classList.toggle('drop-left', side === 'left');
|
||||
this._dropOverlay.classList.toggle('drop-right', side === 'right');
|
||||
this._dropOverlay.classList.toggle('drop-before', side === 'before');
|
||||
this._dropOverlay.classList.toggle('drop-after', side === 'after');
|
||||
}
|
||||
|
||||
if (!this._dropOverlay.parentElement) {
|
||||
@@ -1986,8 +1994,8 @@ class TerminalInstanceDragAndDropController extends Disposable implements IDragA
|
||||
// Dragging terminals
|
||||
if (types.includes('terminals')) {
|
||||
const side = this._getDropSide(e);
|
||||
this._dropOverlay.classList.toggle('drop-left', side === 'left');
|
||||
this._dropOverlay.classList.toggle('drop-right', side === 'right');
|
||||
this._dropOverlay.classList.toggle('drop-before', side === 'before');
|
||||
this._dropOverlay.classList.toggle('drop-after', side === 'after');
|
||||
}
|
||||
|
||||
this._dropOverlay.style.opacity = '1';
|
||||
@@ -2026,13 +2034,24 @@ class TerminalInstanceDragAndDropController extends Disposable implements IDragA
|
||||
this._onDropFile.fire(path);
|
||||
}
|
||||
|
||||
private _getDropSide(e: DragEvent): 'left' | 'right' {
|
||||
private _getDropSide(e: DragEvent): 'before' | 'after' {
|
||||
const target = this._container;
|
||||
if (!target) {
|
||||
return 'right';
|
||||
return 'after';
|
||||
}
|
||||
|
||||
const rect = target.getBoundingClientRect();
|
||||
return e.clientX - rect.left < rect.width / 2 ? 'left' : 'right';
|
||||
return this._getViewOrientation() === Orientation.HORIZONTAL
|
||||
? (e.clientX - rect.left < rect.width / 2 ? 'before' : 'after')
|
||||
: (e.clientY - rect.top < rect.height / 2 ? 'before' : 'after');
|
||||
}
|
||||
|
||||
private _getViewOrientation(): Orientation {
|
||||
const panelPosition = this._layoutService.getPanelPosition();
|
||||
const terminalLocation = this._viewDescriptorService.getViewLocationById(TERMINAL_VIEW_ID);
|
||||
return terminalLocation === ViewContainerLocation.Panel && panelPosition === Position.BOTTOM
|
||||
? Orientation.HORIZONTAL
|
||||
: Orientation.VERTICAL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { localize } from 'vs/nls';
|
||||
import { MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyAndExpr, ContextKeyEqualsExpr, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { TerminalSettingId } from 'vs/platform/terminal/common/terminal';
|
||||
import { IS_SPLIT_TERMINAL_CONTEXT_KEY, KEYBINDING_CONTEXT_TERMINAL_PROCESS_SUPPORTED, KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, TerminalCommandId, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
|
||||
const enum ContextMenuGroup {
|
||||
Create = '1_create',
|
||||
@@ -34,7 +36,8 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.MenubarTerminalMenu, item: {
|
||||
id: MenuId.MenubarTerminalMenu,
|
||||
item: {
|
||||
group: TerminalMenuBarGroup.Create,
|
||||
command: {
|
||||
id: TerminalCommandId.New,
|
||||
@@ -44,7 +47,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.MenubarTerminalMenu, item: {
|
||||
id: MenuId.MenubarTerminalMenu,
|
||||
item: {
|
||||
group: TerminalMenuBarGroup.Create,
|
||||
command: {
|
||||
id: TerminalCommandId.Split,
|
||||
@@ -56,7 +60,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.MenubarTerminalMenu, item: {
|
||||
id: MenuId.MenubarTerminalMenu,
|
||||
item: {
|
||||
group: TerminalMenuBarGroup.Run,
|
||||
command: {
|
||||
id: TerminalCommandId.RunActiveFile,
|
||||
@@ -67,7 +72,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.MenubarTerminalMenu, item: {
|
||||
id: MenuId.MenubarTerminalMenu,
|
||||
item: {
|
||||
group: TerminalMenuBarGroup.Run,
|
||||
command: {
|
||||
id: TerminalCommandId.RunSelectedText,
|
||||
@@ -83,16 +89,18 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
group: ContextMenuGroup.Create,
|
||||
command: {
|
||||
id: TerminalCommandId.Split,
|
||||
title: localize('workbench.action.terminal.split', "Split Terminal")
|
||||
title: terminalStrings.split.value
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.New,
|
||||
title: localize('workbench.action.terminal.new.short', "New Terminal")
|
||||
@@ -101,16 +109,18 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Kill,
|
||||
title: localize('workbench.action.terminal.kill.short', "Kill Terminal")
|
||||
title: terminalStrings.kill.value
|
||||
},
|
||||
group: ContextMenuGroup.Kill
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.CopySelection,
|
||||
title: localize('workbench.action.terminal.copySelection.short', "Copy")
|
||||
@@ -120,7 +130,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Paste,
|
||||
title: localize('workbench.action.terminal.paste.short', "Paste")
|
||||
@@ -130,7 +141,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Clear,
|
||||
title: localize('workbench.action.terminal.clear', "Clear")
|
||||
@@ -139,7 +151,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ShowTabs,
|
||||
title: localize('workbench.action.terminal.showsTabs', "Show Tabs")
|
||||
@@ -149,7 +162,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInstanceContext, item: {
|
||||
id: MenuId.TerminalInstanceContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.SelectAll,
|
||||
title: localize('workbench.action.terminal.selectAll', "Select All"),
|
||||
@@ -164,7 +178,8 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.TerminalTabEmptyAreaContext, item: {
|
||||
id: MenuId.TerminalTabEmptyAreaContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.NewWithProfile,
|
||||
title: localize('workbench.action.terminal.newWithProfile.short', "New Terminal With Profile")
|
||||
@@ -173,7 +188,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabEmptyAreaContext, item: {
|
||||
id: MenuId.TerminalTabEmptyAreaContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.New,
|
||||
title: localize('workbench.action.terminal.new.short', "New Terminal")
|
||||
@@ -187,7 +203,8 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.TerminalNewDropdownContext, item: {
|
||||
id: MenuId.TerminalNewDropdownContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.SelectDefaultProfile,
|
||||
title: { value: localize('workbench.action.terminal.selectDefaultProfile', "Select Default Profile"), original: 'Select Default Profile' }
|
||||
@@ -196,7 +213,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalNewDropdownContext, item: {
|
||||
id: MenuId.TerminalNewDropdownContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ConfigureTerminalSettings,
|
||||
title: localize('workbench.action.terminal.openSettings', "Configure Terminal Settings")
|
||||
@@ -210,7 +228,8 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.ViewTitle, item: {
|
||||
id: MenuId.ViewTitle,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.SwitchTerminal,
|
||||
title: { value: localize('workbench.action.terminal.switchTerminal', "Switch Terminal"), original: 'Switch Terminal' }
|
||||
@@ -222,6 +241,86 @@ export function setupTerminalMenus(): void {
|
||||
ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`)
|
||||
]),
|
||||
}
|
||||
},
|
||||
{
|
||||
// This is used to show instead of tabs when there is only a single terminal
|
||||
id: MenuId.ViewTitle,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Focus,
|
||||
title: terminalStrings.focus
|
||||
},
|
||||
group: 'navigation',
|
||||
order: 0,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.has(`config.${TerminalSettingId.TabsEnabled}`),
|
||||
ContextKeyExpr.or(
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleTerminal'),
|
||||
ContextKeyExpr.equals('terminalCount', 1)
|
||||
),
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleTerminalOrNarrow'),
|
||||
ContextKeyExpr.or(
|
||||
ContextKeyExpr.equals('terminalCount', 1),
|
||||
ContextKeyExpr.has('isTerminalTabsNarrow')
|
||||
)
|
||||
),
|
||||
ContextKeyExpr.and(
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'singleGroup'),
|
||||
ContextKeyExpr.equals('terminalGroupCount', 1)
|
||||
),
|
||||
ContextKeyExpr.equals(`config.${TerminalSettingId.TabsShowActiveTerminal}`, 'always')
|
||||
)
|
||||
]),
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.ViewTitle,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Split,
|
||||
title: terminalStrings.split,
|
||||
icon: Codicon.splitHorizontal
|
||||
},
|
||||
group: 'navigation',
|
||||
order: 2,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`)
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.ViewTitle,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Kill,
|
||||
title: terminalStrings.kill,
|
||||
icon: Codicon.trash
|
||||
},
|
||||
group: 'navigation',
|
||||
order: 3,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID),
|
||||
ContextKeyExpr.not(`config.${TerminalSettingId.TabsEnabled}`)
|
||||
])
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.ViewTitle,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.CreateWithProfileButton,
|
||||
title: TerminalCommandId.CreateWithProfileButton
|
||||
},
|
||||
group: 'navigation',
|
||||
order: 0,
|
||||
when: ContextKeyAndExpr.create([
|
||||
ContextKeyEqualsExpr.create('view', TERMINAL_VIEW_ID)
|
||||
])
|
||||
}
|
||||
}
|
||||
]
|
||||
);
|
||||
@@ -229,16 +328,18 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.TerminalInlineTabContext, item: {
|
||||
id: MenuId.TerminalInlineTabContext,
|
||||
item: {
|
||||
group: ContextMenuGroup.Create,
|
||||
command: {
|
||||
id: TerminalCommandId.Split,
|
||||
title: localize('workbench.action.terminal.split', "Split Terminal")
|
||||
title: terminalStrings.split.value
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInlineTabContext, item: {
|
||||
id: MenuId.TerminalInlineTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ChangeIcon,
|
||||
title: localize('workbench.action.terminal.changeIcon', "Change Icon...")
|
||||
@@ -248,7 +349,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInlineTabContext, item: {
|
||||
id: MenuId.TerminalInlineTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ChangeColor,
|
||||
title: localize('workbench.action.terminal.changeColor', "Change Color...")
|
||||
@@ -258,7 +360,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInlineTabContext, item: {
|
||||
id: MenuId.TerminalInlineTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Rename,
|
||||
title: localize('workbench.action.terminal.rename', "Rename...")
|
||||
@@ -267,10 +370,11 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalInlineTabContext, item: {
|
||||
id: MenuId.TerminalInlineTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.Kill,
|
||||
title: localize('workbench.action.terminal.kill.short', "Kill Terminal")
|
||||
title: terminalStrings.kill.value
|
||||
},
|
||||
group: ContextMenuGroup.Kill
|
||||
}
|
||||
@@ -281,16 +385,18 @@ export function setupTerminalMenus(): void {
|
||||
MenuRegistry.appendMenuItems(
|
||||
[
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.SplitInstance,
|
||||
title: localize('workbench.action.terminal.splitInstance', "Split Terminal"),
|
||||
title: terminalStrings.split.value,
|
||||
},
|
||||
group: ContextMenuGroup.Create
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.RenameInstance,
|
||||
title: localize('workbench.action.terminal.renameInstance', "Rename...")
|
||||
@@ -299,7 +405,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ChangeIconInstance,
|
||||
title: localize('workbench.action.terminal.changeIcon', "Change Icon...")
|
||||
@@ -308,7 +415,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.ChangeColorInstance,
|
||||
title: localize('workbench.action.terminal.changeColor', "Change Color...")
|
||||
@@ -317,7 +425,8 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
group: ContextMenuGroup.Config,
|
||||
command: {
|
||||
id: TerminalCommandId.JoinInstance,
|
||||
@@ -327,20 +436,22 @@ export function setupTerminalMenus(): void {
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
group: ContextMenuGroup.Config,
|
||||
command: {
|
||||
id: TerminalCommandId.UnsplitInstance,
|
||||
title: localize('workbench.action.terminal.unsplitInstance', "Unsplit Terminal")
|
||||
title: terminalStrings.unsplit.value
|
||||
},
|
||||
when: ContextKeyExpr.and(KEYBINDING_CONTEXT_TERMINAL_TABS_SINGULAR_SELECTION, IS_SPLIT_TERMINAL_CONTEXT_KEY)
|
||||
}
|
||||
},
|
||||
{
|
||||
id: MenuId.TerminalTabContext, item: {
|
||||
id: MenuId.TerminalTabContext,
|
||||
item: {
|
||||
command: {
|
||||
id: TerminalCommandId.KillInstance,
|
||||
title: localize('workbench.action.terminal.killInstance', "Kill Terminal")
|
||||
title: terminalStrings.kill.value
|
||||
},
|
||||
group: ContextMenuGroup.Kill,
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { TerminalCommandId } from 'vs/workbench/contrib/terminal/common/terminal
|
||||
import { IThemeService, ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
import { killTerminalIcon, renameTerminalIcon } from 'vs/workbench/contrib/terminal/browser/terminalIcons';
|
||||
import { getColorClass, getIconId, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
|
||||
export class TerminalQuickAccessProvider extends PickerQuickAccessProvider<IPickerQuickAccessItem> {
|
||||
|
||||
@@ -57,7 +58,7 @@ export class TerminalQuickAccessProvider extends PickerQuickAccessProvider<IPick
|
||||
},
|
||||
{
|
||||
iconClass: ThemeIcon.asClassName(killTerminalIcon),
|
||||
tooltip: localize('killTerminal', "Kill Terminal Instance")
|
||||
tooltip: terminalStrings.kill.value
|
||||
}
|
||||
],
|
||||
iconClasses,
|
||||
|
||||
@@ -63,7 +63,7 @@ export class TerminalService implements ITerminalService {
|
||||
private _linkProviderDisposables: Map<ITerminalExternalLinkProvider, IDisposable[]> = new Map();
|
||||
private _processSupportContextKey: IContextKey<boolean>;
|
||||
private readonly _localTerminalService?: ILocalTerminalService;
|
||||
private readonly _offProcessTerminalService?: IOffProcessTerminalService;
|
||||
private readonly _primaryOffProcessTerminalService?: IOffProcessTerminalService;
|
||||
private _profilesReadyBarrier: AutoOpenBarrier;
|
||||
private _availableProfiles: ITerminalProfile[] | undefined;
|
||||
private _configHelper: TerminalConfigHelper;
|
||||
@@ -210,7 +210,7 @@ export class TerminalService implements ITerminalService {
|
||||
: enableTerminalReconnection
|
||||
? this._localTerminalsInitPromise = this._reconnectToLocalTerminals()
|
||||
: Promise.resolve();
|
||||
this._offProcessTerminalService = !!this._environmentService.remoteAuthority ? this._remoteTerminalService : this._localTerminalService;
|
||||
this._primaryOffProcessTerminalService = !!this._environmentService.remoteAuthority ? this._remoteTerminalService : this._localTerminalService;
|
||||
initPromise.then(() => this._setConnected());
|
||||
|
||||
// Wait up to 5 seconds for profiles to be ready so it's assured that we know the actual
|
||||
@@ -376,12 +376,11 @@ export class TerminalService implements ITerminalService {
|
||||
}
|
||||
|
||||
private async _detectProfiles(includeDetectedProfiles?: boolean): Promise<ITerminalProfile[]> {
|
||||
const offProcService = this._offProcessTerminalService;
|
||||
if (!offProcService) {
|
||||
if (!this._primaryOffProcessTerminalService) {
|
||||
return this._availableProfiles || [];
|
||||
}
|
||||
const platform = await this._getPlatformKey();
|
||||
return offProcService?.getProfiles(this._configurationService.getValue(`${TerminalSettingPrefix.Profiles}${platform}`), this._configurationService.getValue(`${TerminalSettingPrefix.DefaultProfile}${platform}`), includeDetectedProfiles);
|
||||
return this._primaryOffProcessTerminalService?.getProfiles(this._configurationService.getValue(`${TerminalSettingPrefix.Profiles}${platform}`), this._configurationService.getValue(`${TerminalSettingPrefix.DefaultProfile}${platform}`), includeDetectedProfiles);
|
||||
}
|
||||
|
||||
private _onBeforeShutdown(reason: ShutdownReason): boolean | Promise<boolean> {
|
||||
@@ -441,7 +440,7 @@ export class TerminalService implements ITerminalService {
|
||||
const state: ITerminalsLayoutInfoById = {
|
||||
tabs: this.terminalGroups.map(g => g.getLayoutInfo(g === this.getActiveGroup()))
|
||||
};
|
||||
this._offProcessTerminalService?.setTerminalLayoutInfo(state);
|
||||
this._primaryOffProcessTerminalService?.setTerminalLayoutInfo(state);
|
||||
}
|
||||
|
||||
@debounce(500)
|
||||
@@ -449,7 +448,7 @@ export class TerminalService implements ITerminalService {
|
||||
if (!this.configHelper.config.enablePersistentSessions || !instance || !instance.persistentProcessId || !instance.title) {
|
||||
return;
|
||||
}
|
||||
this._offProcessTerminalService?.updateTitle(instance.persistentProcessId, instance.title, instance.titleSource);
|
||||
this._primaryOffProcessTerminalService?.updateTitle(instance.persistentProcessId, instance.title, instance.titleSource);
|
||||
}
|
||||
|
||||
@debounce(500)
|
||||
@@ -457,7 +456,7 @@ export class TerminalService implements ITerminalService {
|
||||
if (!this.configHelper.config.enablePersistentSessions || !instance || !instance.persistentProcessId || !instance.icon) {
|
||||
return;
|
||||
}
|
||||
this._offProcessTerminalService?.updateIcon(instance.persistentProcessId, instance.icon, instance.color);
|
||||
this._primaryOffProcessTerminalService?.updateIcon(instance.persistentProcessId, instance.icon, instance.color);
|
||||
}
|
||||
|
||||
private _removeGroup(group: ITerminalGroup): void {
|
||||
@@ -743,7 +742,7 @@ export class TerminalService implements ITerminalService {
|
||||
this._onInstancesChanged.fire();
|
||||
}
|
||||
|
||||
moveInstance(source: ITerminalInstance, target: ITerminalInstance, side: 'left' | 'right'): void {
|
||||
moveInstance(source: ITerminalInstance, target: ITerminalInstance, side: 'before' | 'after'): void {
|
||||
const sourceGroup = this.getGroupForInstance(source);
|
||||
const targetGroup = this.getGroupForInstance(target);
|
||||
if (!sourceGroup || !targetGroup) {
|
||||
@@ -758,7 +757,7 @@ export class TerminalService implements ITerminalService {
|
||||
}
|
||||
|
||||
// Rearrange within the target group
|
||||
const index = targetGroup.terminalInstances.indexOf(target) + (side === 'right' ? 1 : 0);
|
||||
const index = targetGroup.terminalInstances.indexOf(target) + (side === 'after' ? 1 : 0);
|
||||
targetGroup.moveInstance(source, index);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import { Disposable, DisposableStore, dispose, IDisposable, toDisposable } from
|
||||
import { IListDragAndDrop, IListDragOverReaction, IListRenderer, ListDragOverEffect } from 'vs/base/browser/ui/list/list';
|
||||
import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { disposableTimeout } from 'vs/base/common/async';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { ElementsDragAndDropData, NativeDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getColorClass, getIconId, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
@@ -41,6 +41,8 @@ import { once } from 'vs/base/common/functional';
|
||||
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { containsDragType } from 'vs/workbench/browser/dnd';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -436,10 +438,10 @@ class TerminalTabsRenderer implements IListRenderer<ITerminalInstance, ITerminal
|
||||
fillActionBar(instance: ITerminalInstance, template: ITerminalTabEntryTemplate): void {
|
||||
// If the instance is within the selection, split all selected
|
||||
const actions = [
|
||||
new Action(TerminalCommandId.SplitInstance, localize('terminal.split', "Split"), ThemeIcon.asClassName(Codicon.splitHorizontal), true, async () => {
|
||||
new Action(TerminalCommandId.SplitInstance, terminalStrings.split.short, ThemeIcon.asClassName(Codicon.splitHorizontal), true, async () => {
|
||||
this._runForSelectionOrInstance(instance, e => this._terminalService.splitInstance(e));
|
||||
}),
|
||||
new Action(TerminalCommandId.KillInstance, localize('terminal.kill', "Kill"), ThemeIcon.asClassName(Codicon.trashcan), true, async () => {
|
||||
new Action(TerminalCommandId.KillInstance, terminalStrings.kill.short, ThemeIcon.asClassName(Codicon.trashcan), true, async () => {
|
||||
this._runForSelectionOrInstance(instance, e => e.dispose());
|
||||
})
|
||||
];
|
||||
@@ -547,7 +549,11 @@ class TerminalTabsDragAndDrop implements IListDragAndDrop<ITerminalInstance> {
|
||||
}
|
||||
|
||||
onDragOver(data: IDragAndDropData, targetInstance: ITerminalInstance | undefined, targetIndex: number | undefined, originalEvent: DragEvent): boolean | IListDragOverReaction {
|
||||
let result = true;
|
||||
if (data instanceof NativeDragAndDropData) {
|
||||
if (!containsDragType(originalEvent, DataTransfers.FILES, DataTransfers.RESOURCES)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const didChangeAutoFocusInstance = this._autoFocusInstance !== targetInstance;
|
||||
if (didChangeAutoFocusInstance) {
|
||||
@@ -556,7 +562,7 @@ class TerminalTabsDragAndDrop implements IListDragAndDrop<ITerminalInstance> {
|
||||
}
|
||||
|
||||
if (!targetInstance) {
|
||||
return result;
|
||||
return data instanceof ElementsDragAndDropData;
|
||||
}
|
||||
|
||||
if (didChangeAutoFocusInstance) {
|
||||
|
||||
@@ -42,6 +42,7 @@ import { dispose, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ColorScheme } from 'vs/platform/theme/common/theme';
|
||||
import { getColorClass, getUriClasses } from 'vs/workbench/contrib/terminal/browser/terminalIcon';
|
||||
import { terminalStrings } from 'vs/workbench/contrib/terminal/common/terminalStrings';
|
||||
|
||||
export class TerminalViewPane extends ViewPane {
|
||||
private _actions: IAction[] | undefined;
|
||||
@@ -257,7 +258,7 @@ export class TerminalViewPane extends ViewPane {
|
||||
},
|
||||
{
|
||||
id: TerminalCommandId.Split,
|
||||
title: nls.localize('terminal.split', "Split Terminal"),
|
||||
title: terminalStrings.split.value,
|
||||
icon: Codicon.splitHorizontal
|
||||
},
|
||||
undefined);
|
||||
@@ -385,7 +386,7 @@ class SingleTerminalTabActionViewItem extends MenuEntryActionViewItem {
|
||||
},
|
||||
{
|
||||
id: TerminalCommandId.Split,
|
||||
title: nls.localize('workbench.action.terminal.split', "Split Terminal"),
|
||||
title: terminalStrings.split.value,
|
||||
icon: Codicon.splitHorizontal
|
||||
},
|
||||
undefined,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user