mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 13:00:58 +00:00
Merge branch 'master' into sandy081/web-playground/login
This commit is contained in:
commit
a4a9fcb7dd
|
@ -73,6 +73,7 @@ RUN apt-get update \
|
|||
libnss3 \
|
||||
libxss1 \
|
||||
libasound2 \
|
||||
libgbm1 \
|
||||
xfonts-base \
|
||||
xfonts-terminus \
|
||||
fonts-noto \
|
||||
|
|
77
.vscode/searches/TrustedTypes.code-search
vendored
77
.vscode/searches/TrustedTypes.code-search
vendored
|
@ -4,24 +4,24 @@
|
|||
# Excluding: *.test.ts
|
||||
# ContextLines: 3
|
||||
|
||||
26 results - 15 files
|
||||
22 results - 14 files
|
||||
|
||||
src/vs/base/browser/markdownRenderer.ts:
|
||||
156 const strValue = values[0];
|
||||
157 const span = element.querySelector(`div[data-code="${id}"]`);
|
||||
158 if (span) {
|
||||
159: span.innerHTML = strValue;
|
||||
160 }
|
||||
161 }).catch(err => {
|
||||
162 // ignore
|
||||
161 const strValue = values[0];
|
||||
162 const span = element.querySelector(`div[data-code="${id}"]`);
|
||||
163 if (span) {
|
||||
164: span.innerHTML = strValue;
|
||||
165 }
|
||||
166 }).catch(err => {
|
||||
167 // ignore
|
||||
|
||||
238 return true;
|
||||
239 }
|
||||
240
|
||||
241: element.innerHTML = insane(renderedMarkdown, {
|
||||
242 allowedSchemes,
|
||||
243 // allowedTags should included everything that markdown renders to.
|
||||
244 // Since we have our own sanitize function for marked, it's possible we missed some tag so let insane make sure.
|
||||
243 return true;
|
||||
244 }
|
||||
245
|
||||
246: element.innerHTML = insane(renderedMarkdown, {
|
||||
247 allowedSchemes,
|
||||
248 // allowedTags should included everything that markdown renders to.
|
||||
249 // Since we have our own sanitize function for marked, it's possible we missed some tag so let insane make sure.
|
||||
|
||||
src/vs/base/browser/ui/contextview/contextview.ts:
|
||||
157 this.shadowRootHostElement = DOM.$('.shadow-root-host');
|
||||
|
@ -32,47 +32,14 @@ src/vs/base/browser/ui/contextview/contextview.ts:
|
|||
162 ${SHADOW_ROOT_CSS}
|
||||
163 </style>
|
||||
|
||||
src/vs/code/electron-browser/workbench/workbench.js:
|
||||
124 const style = document.createElement('style');
|
||||
125 style.className = 'initialShellColors';
|
||||
126 document.head.appendChild(style);
|
||||
127: style.innerHTML = `body { background-color: ${shellBackground}; color: ${shellForeground}; margin: 0; padding: 0; }`;
|
||||
128
|
||||
129 if (data && data.layoutInfo) {
|
||||
130 // restore parts if possible (we might not always store layout info)
|
||||
|
||||
150
|
||||
151 if (configuration.folderUri || configuration.workspace) {
|
||||
152 // folder or workspace -> status bar color, sidebar
|
||||
153: splash.innerHTML = `
|
||||
154 <div style="position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;"></div>
|
||||
155 <div style="position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};"></div>
|
||||
156 <div style="position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: ${layoutInfo.activityBarWidth}px; width: ${layoutInfo.sideBarWidth}px; background-color: ${colorInfo.sideBarBackground};"></div>
|
||||
|
||||
158 `;
|
||||
159 } else {
|
||||
160 // empty -> speical status bar color, no sidebar
|
||||
161: splash.innerHTML = `
|
||||
162 <div style="position: absolute; width: 100%; left: 0; top: 0; height: ${layoutInfo.titleBarHeight}px; background-color: ${colorInfo.titleBarBackground}; -webkit-app-region: drag;"></div>
|
||||
163 <div style="position: absolute; height: calc(100% - ${layoutInfo.titleBarHeight}px); top: ${layoutInfo.titleBarHeight}px; ${layoutInfo.sideBarSide}: 0; width: ${layoutInfo.activityBarWidth}px; background-color: ${colorInfo.activityBarBackground};"></div>
|
||||
164 <div style="position: absolute; width: 100%; bottom: 0; left: 0; height: ${layoutInfo.statusBarHeight}px; background-color: ${colorInfo.statusBarNoFolderBackground};"></div>
|
||||
|
||||
src/vs/code/electron-sandbox/issue/issueReporterMain.ts:
|
||||
57 const platformClass = platform.isWindows ? 'windows' : platform.isLinux ? 'linux' : 'mac';
|
||||
58 addClass(document.body, platformClass); // used by our fonts
|
||||
59
|
||||
60: document.body.innerHTML = BaseHtml();
|
||||
61 const issueReporter = new IssueReporter(configuration);
|
||||
62 issueReporter.render();
|
||||
63 document.body.style.display = 'block';
|
||||
|
||||
244 content.push(`.monaco-text-button:not(.disabled):hover, .monaco-text-button:focus { background-color: ${styles.buttonHoverBackground} !important; }`);
|
||||
245 }
|
||||
246
|
||||
247: styleTag.innerHTML = content.join('\n');
|
||||
248 document.head.appendChild(styleTag);
|
||||
249 document.body.style.color = styles.color || '';
|
||||
250 }
|
||||
57 const platformClass = platform.isWindows ? 'windows' : platform.isLinux ? 'linux' : 'mac';
|
||||
58 addClass(document.body, platformClass); // used by our fonts
|
||||
59
|
||||
60: document.body.innerHTML = BaseHtml();
|
||||
61 const issueReporter = new IssueReporter(configuration);
|
||||
62 issueReporter.render();
|
||||
63 document.body.style.display = 'block';
|
||||
|
||||
src/vs/code/electron-sandbox/processExplorer/processExplorerMain.ts:
|
||||
320 content.push(`.highest { color: ${styles.highlightForeground}; }`);
|
||||
|
|
18
.vscode/searches/es6.code-search
vendored
18
.vscode/searches/es6.code-search
vendored
|
@ -2,7 +2,7 @@
|
|||
# Flags: CaseSensitive WordMatch
|
||||
# ContextLines: 2
|
||||
|
||||
14 results - 4 files
|
||||
12 results - 4 files
|
||||
|
||||
src/vs/base/browser/dom.ts:
|
||||
83 };
|
||||
|
@ -24,21 +24,9 @@ src/vs/base/browser/dom.ts:
|
|||
src/vs/base/common/arrays.ts:
|
||||
401
|
||||
402 /**
|
||||
403: * @deprecated ES6: use `Array.findIndex`
|
||||
403: * @deprecated ES6: use `Array.find`
|
||||
404 */
|
||||
405 export function firstIndex<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean): number {
|
||||
|
||||
417
|
||||
418 /**
|
||||
419: * @deprecated ES6: use `Array.find`
|
||||
420 */
|
||||
421 export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T): T;
|
||||
|
||||
568
|
||||
569 /**
|
||||
570: * @deprecated ES6: use `Array.find`
|
||||
571 */
|
||||
572 export function find<T>(arr: ArrayLike<T>, predicate: (value: T, index: number, arr: ArrayLike<T>) => any): T | undefined {
|
||||
405 export function first<T>(array: ReadonlyArray<T>, fn: (item: T) => boolean, notFoundValue: T): T;
|
||||
|
||||
src/vs/base/common/objects.ts:
|
||||
115
|
||||
|
|
58
.vscode/searches/ts36031.code-search
vendored
58
.vscode/searches/ts36031.code-search
vendored
|
@ -2,18 +2,52 @@
|
|||
# Flags: RegExp
|
||||
# ContextLines: 2
|
||||
|
||||
2 results - 2 files
|
||||
8 results - 4 files
|
||||
|
||||
src/vs/base/browser/ui/tree/asyncDataTree.ts:
|
||||
243 } : () => 'treeitem',
|
||||
244 isChecked: options.accessibilityProvider!.isChecked ? (e) => {
|
||||
245: return !!(options.accessibilityProvider?.isChecked!(e.element as T));
|
||||
246 } : undefined,
|
||||
247 getAriaLabel(e) {
|
||||
241 } : () => 'treeitem',
|
||||
242 isChecked: options.accessibilityProvider!.isChecked ? (e) => {
|
||||
243: return !!(options.accessibilityProvider?.isChecked!(e.element as T));
|
||||
244 } : undefined,
|
||||
245 getAriaLabel(e) {
|
||||
|
||||
src/vs/workbench/contrib/debug/browser/debugConfigurationManager.ts:
|
||||
254
|
||||
255 return debugDynamicExtensions.map(e => {
|
||||
256: const type = e.contributes?.debuggers![0].type!;
|
||||
257 return {
|
||||
258 label: this.getDebuggerLabel(type)!,
|
||||
src/vs/platform/list/browser/listService.ts:
|
||||
463
|
||||
464 if (typeof options?.openOnSingleClick !== 'boolean' && options?.configurationService) {
|
||||
465: this.openOnSingleClick = options?.configurationService!.getValue(openModeSettingKey) !== 'doubleClick';
|
||||
466 this._register(options?.configurationService.onDidChangeConfiguration(() => {
|
||||
467: this.openOnSingleClick = options?.configurationService!.getValue(openModeSettingKey) !== 'doubleClick';
|
||||
468 }));
|
||||
469 } else {
|
||||
|
||||
src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts:
|
||||
1526
|
||||
1527 await this._ensureActiveKernel();
|
||||
1528: await this._activeKernel?.cancelNotebookCell!(this._notebookViewModel!.uri, undefined);
|
||||
1529 }
|
||||
1530
|
||||
|
||||
1535
|
||||
1536 await this._ensureActiveKernel();
|
||||
1537: await this._activeKernel?.executeNotebookCell!(this._notebookViewModel!.uri, undefined);
|
||||
1538 }
|
||||
1539
|
||||
|
||||
1553
|
||||
1554 await this._ensureActiveKernel();
|
||||
1555: await this._activeKernel?.cancelNotebookCell!(this._notebookViewModel!.uri, cell.handle);
|
||||
1556 }
|
||||
1557
|
||||
|
||||
1567
|
||||
1568 await this._ensureActiveKernel();
|
||||
1569: await this._activeKernel?.executeNotebookCell!(this._notebookViewModel!.uri, cell.handle);
|
||||
1570 }
|
||||
1571
|
||||
|
||||
src/vs/workbench/contrib/webview/electron-browser/iframeWebviewElement.ts:
|
||||
89 .then(() => this._resourceRequestManager.ensureReady())
|
||||
90 .then(() => {
|
||||
91: this.element?.contentWindow!.postMessage({ channel, args: data }, '*');
|
||||
92 });
|
||||
93 }
|
||||
|
|
|
@ -14,10 +14,10 @@ resources:
|
|||
image: vscodehub.azurecr.io/vscode-linux-build-agent:x64
|
||||
endpoint: VSCodeHub
|
||||
- container: vscode-arm64
|
||||
image: vscodehub.azurecr.io/vscode-linux-build-agent:buster-arm64
|
||||
image: vscodehub.azurecr.io/vscode-linux-build-agent:stretch-arm64
|
||||
endpoint: VSCodeHub
|
||||
- container: vscode-armhf
|
||||
image: vscodehub.azurecr.io/vscode-linux-build-agent:buster-armhf
|
||||
image: vscodehub.azurecr.io/vscode-linux-build-agent:stretch-armhf
|
||||
endpoint: VSCodeHub
|
||||
- container: snapcraft
|
||||
image: snapcore/snapcraft:stable
|
||||
|
|
|
@ -206,6 +206,10 @@
|
|||
"name": "vs/workbench/contrib/webview",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/webviewPanel",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/customEditor",
|
||||
"project": "vscode-workbench"
|
||||
|
|
|
@ -507,7 +507,7 @@ suite('Notebook API tests', () => {
|
|||
// inserting two new cells
|
||||
{
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceCells(document.uri, 0, 0, [{
|
||||
edit.replaceNotebookCells(document.uri, 0, 0, [{
|
||||
cellKind: vscode.CellKind.Markdown,
|
||||
language: 'markdown',
|
||||
metadata: undefined,
|
||||
|
@ -532,8 +532,8 @@ suite('Notebook API tests', () => {
|
|||
// deleting cell 1 and 3
|
||||
{
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceCells(document.uri, 0, 1, []);
|
||||
edit.replaceCells(document.uri, 2, 3, []);
|
||||
edit.replaceNotebookCells(document.uri, 0, 1, []);
|
||||
edit.replaceNotebookCells(document.uri, 2, 3, []);
|
||||
const success = await vscode.workspace.applyEdit(edit);
|
||||
assert.strictEqual(success, true);
|
||||
}
|
||||
|
@ -544,7 +544,7 @@ suite('Notebook API tests', () => {
|
|||
// replacing all cells
|
||||
{
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceCells(document.uri, 0, 1, [{
|
||||
edit.replaceNotebookCells(document.uri, 0, 1, [{
|
||||
cellKind: vscode.CellKind.Markdown,
|
||||
language: 'markdown',
|
||||
metadata: undefined,
|
||||
|
@ -567,7 +567,7 @@ suite('Notebook API tests', () => {
|
|||
// remove all cells
|
||||
{
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceCells(document.uri, 0, document.cells.length, []);
|
||||
edit.replaceNotebookCells(document.uri, 0, document.cells.length, []);
|
||||
const success = await vscode.workspace.applyEdit(edit);
|
||||
assert.strictEqual(success, true);
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ suite('Notebook API tests', () => {
|
|||
assert.strictEqual(document.cells.length, 1);
|
||||
|
||||
const edit = new vscode.WorkspaceEdit();
|
||||
edit.replaceCells(document.uri, 0, 0, [{
|
||||
edit.replaceNotebookCells(document.uri, 0, 0, [{
|
||||
cellKind: vscode.CellKind.Markdown,
|
||||
language: 'markdown',
|
||||
metadata: undefined,
|
||||
|
@ -1228,6 +1228,43 @@ suite('regression', () => {
|
|||
// await vscode.commands.executeCommand('workbench.action.closeAllEditors');
|
||||
// });
|
||||
|
||||
test('#106657. Opening a notebook from markers view is broken ', async function () {
|
||||
assertInitalState();
|
||||
const resource = await createRandomFile('', undefined, 'first', '.vsctestnb');
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
|
||||
const document = vscode.notebook.activeNotebookEditor?.document!;
|
||||
const [cell] = document.cells;
|
||||
|
||||
await saveAllFilesAndCloseAll(document.uri);
|
||||
assert.strictEqual(vscode.notebook.activeNotebookEditor, undefined);
|
||||
|
||||
// opening a cell-uri opens a notebook editor
|
||||
await vscode.commands.executeCommand('vscode.open', cell.uri, vscode.ViewColumn.Active);
|
||||
|
||||
assert.strictEqual(!!vscode.notebook.activeNotebookEditor, true);
|
||||
assert.strictEqual(vscode.notebook.activeNotebookEditor?.document.uri.toString(), resource.toString());
|
||||
});
|
||||
|
||||
test('Cannot open notebook from cell-uri with vscode.open-command', async function () {
|
||||
this.skip();
|
||||
assertInitalState();
|
||||
const resource = await createRandomFile('', undefined, 'first', '.vsctestnb');
|
||||
await vscode.commands.executeCommand('vscode.openWith', resource, 'notebookCoreTest');
|
||||
|
||||
const document = vscode.notebook.activeNotebookEditor?.document!;
|
||||
const [cell] = document.cells;
|
||||
|
||||
await saveAllFilesAndCloseAll(document.uri);
|
||||
assert.strictEqual(vscode.notebook.activeNotebookEditor, undefined);
|
||||
|
||||
// BUG is that the editor opener (https://github.com/microsoft/vscode/blob/8e7877bdc442f1e83a7fec51920d82b696139129/src/vs/editor/browser/services/openerService.ts#L69)
|
||||
// removes the fragment if it matches something numeric. For notebooks that's not wanted...
|
||||
await vscode.commands.executeCommand('vscode.open', cell.uri);
|
||||
|
||||
assert.strictEqual(vscode.notebook.activeNotebookEditor?.document.uri.toString(), resource.toString());
|
||||
});
|
||||
|
||||
test('#97830, #97764. Support switch to other editor types', async function () {
|
||||
assertInitalState();
|
||||
const resource = await createRandomFile('', undefined, 'empty', '.vsctestnb');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/x-@@NAME@@-workspace">
|
||||
<comment>@@NAME_LONG@@ Workspace</comment>
|
||||
<glob pattern="*.code-workspace"/>
|
||||
</mime-type>
|
||||
<mime-type type="application/x-@@NAME@@-workspace">
|
||||
<comment>@@NAME_LONG@@ Workspace</comment>
|
||||
<glob pattern="*.code-workspace"/>
|
||||
</mime-type>
|
||||
</mime-info>
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { renderCodiconsRegex } from 'vs/base/common/codicons';
|
||||
|
||||
export function renderCodiconsAsElement(text: string): Array<HTMLSpanElement | string> {
|
||||
const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
|
||||
export function renderCodicons(text: string): Array<HTMLSpanElement | string> {
|
||||
const elements = new Array<HTMLSpanElement | string>();
|
||||
let match: RegExpMatchArray | null;
|
||||
|
||||
|
@ -24,4 +25,4 @@ export function renderCodiconsAsElement(text: string): Array<HTMLSpanElement | s
|
|||
elements.push(text.substring(textStart));
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,17 +83,17 @@ const _classList: IDomClassList = new class implements IDomClassList {
|
|||
};
|
||||
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const hasClass: (node: HTMLElement | SVGElement, className: string) => boolean = _classList.hasClass.bind(_classList);
|
||||
export function hasClass(node: HTMLElement | SVGElement, className: string): boolean { return _classList.hasClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const addClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.addClass.bind(_classList);
|
||||
export function addClass(node: HTMLElement | SVGElement, className: string): void { return _classList.addClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const addClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.addClasses.bind(_classList);
|
||||
export function addClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void { return _classList.addClasses(node, ...classNames); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const removeClass: (node: HTMLElement | SVGElement, className: string) => void = _classList.removeClass.bind(_classList);
|
||||
export function removeClass(node: HTMLElement | SVGElement, className: string): void { return _classList.removeClass(node, className); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const removeClasses: (node: HTMLElement | SVGElement, ...classNames: string[]) => void = _classList.removeClasses.bind(_classList);
|
||||
export function removeClasses(node: HTMLElement | SVGElement, ...classNames: string[]): void { return _classList.removeClasses(node, ...classNames); }
|
||||
/** @deprecated ES6 - use classList*/
|
||||
export const toggleClass: (node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean) => void = _classList.toggleClass.bind(_classList);
|
||||
export function toggleClass(node: HTMLElement | SVGElement, className: string, shouldHaveIt?: boolean): void { return _classList.toggleClass(node, className, shouldHaveIt); }
|
||||
|
||||
class DomListener implements IDisposable {
|
||||
|
||||
|
@ -1277,3 +1277,66 @@ export function triggerDownload(dataOrUri: Uint8Array | URI, name: string): void
|
|||
// Ensure to remove the element from DOM eventually
|
||||
setTimeout(() => document.body.removeChild(anchor));
|
||||
}
|
||||
|
||||
export enum DetectedFullscreenMode {
|
||||
|
||||
/**
|
||||
* The document is fullscreen, e.g. because an element
|
||||
* in the document requested to be fullscreen.
|
||||
*/
|
||||
DOCUMENT = 1,
|
||||
|
||||
/**
|
||||
* The browser is fullsreen, e.g. because the user enabled
|
||||
* native window fullscreen for it.
|
||||
*/
|
||||
BROWSER
|
||||
}
|
||||
|
||||
export interface IDetectedFullscreen {
|
||||
|
||||
/**
|
||||
* Figure out if the document is fullscreen or the browser.
|
||||
*/
|
||||
mode: DetectedFullscreenMode;
|
||||
|
||||
/**
|
||||
* Wether we know for sure that we are in fullscreen mode or
|
||||
* it is a guess.
|
||||
*/
|
||||
guess: boolean;
|
||||
}
|
||||
|
||||
export function detectFullscreen(): IDetectedFullscreen | null {
|
||||
|
||||
// Browser fullscreen: use DOM APIs to detect
|
||||
if (document.fullscreenElement || (<any>document).webkitFullscreenElement || (<any>document).webkitIsFullScreen) {
|
||||
return { mode: DetectedFullscreenMode.DOCUMENT, guess: false };
|
||||
}
|
||||
|
||||
// There is no standard way to figure out if the browser
|
||||
// is using native fullscreen. Via checking on screen
|
||||
// height and comparing that to window height, we can guess
|
||||
// it though.
|
||||
|
||||
if (window.innerHeight === screen.height) {
|
||||
// if the height of the window matches the screen height, we can
|
||||
// safely assume that the browser is fullscreen because no browser
|
||||
// chrome is taking height away (e.g. like toolbars).
|
||||
return { mode: DetectedFullscreenMode.BROWSER, guess: false };
|
||||
}
|
||||
|
||||
if (platform.isMacintosh || platform.isLinux) {
|
||||
// macOS and Linux do not properly report `innerHeight`, only Windows does
|
||||
if (window.outerHeight === screen.height && window.outerWidth === screen.width) {
|
||||
// if the height of the browser matches the screen height, we can
|
||||
// only guess that we are in fullscreen. It is also possible that
|
||||
// the user has turned off taskbars in the OS and the browser is
|
||||
// simply able to span the entire size of the screen.
|
||||
return { mode: DetectedFullscreenMode.BROWSER, guess: true };
|
||||
}
|
||||
}
|
||||
|
||||
// Not in fullscreen
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@ import { cloneAndChange } from 'vs/base/common/objects';
|
|||
import { escape } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { renderCodicons, markdownEscapeEscapedCodicons } from 'vs/base/common/codicons';
|
||||
import { markdownEscapeEscapedCodicons } from 'vs/base/common/codicons';
|
||||
import { resolvePath } from 'vs/base/common/resources';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export interface MarkedOptions extends marked.MarkedOptions {
|
||||
baseUrl?: never;
|
||||
|
@ -143,7 +144,11 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
|||
}
|
||||
};
|
||||
renderer.paragraph = (text): string => {
|
||||
return `<p>${markdown.supportThemeIcons ? renderCodicons(text) : text}</p>`;
|
||||
if (markdown.supportThemeIcons) {
|
||||
const elements = renderCodicons(text);
|
||||
text = elements.map(e => typeof e === 'string' ? e : e.outerHTML).join('');
|
||||
}
|
||||
return `<p>${text}</p>`;
|
||||
};
|
||||
|
||||
if (options.codeBlockRenderer) {
|
||||
|
|
|
@ -9,12 +9,12 @@ import * as nls from 'vs/nls';
|
|||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { SelectBox, ISelectOptionItem, ISelectBoxOptions } from 'vs/base/browser/ui/selectBox/selectBox';
|
||||
import { IAction, IActionRunner, Action, IActionChangeEvent, ActionRunner, Separator, IActionViewItem } from 'vs/base/common/actions';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { EventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { EventType as TouchEventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { DataTransfers } from 'vs/base/browser/dnd';
|
||||
import { isFirefox } from 'vs/base/browser/browser';
|
||||
import { $, addClasses, addDisposableListener, append, EventHelper, EventLike, EventType, removeClasses, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IBaseActionViewItemOptions {
|
||||
draggable?: boolean;
|
||||
|
@ -107,19 +107,19 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
|||
|
||||
if (isFirefox) {
|
||||
// Firefox: requires to set a text data transfer to get going
|
||||
this._register(DOM.addDisposableListener(container, DOM.EventType.DRAG_START, e => e.dataTransfer?.setData(DataTransfers.TEXT, this._action.label)));
|
||||
this._register(addDisposableListener(container, EventType.DRAG_START, e => e.dataTransfer?.setData(DataTransfers.TEXT, this._action.label)));
|
||||
}
|
||||
}
|
||||
|
||||
this._register(DOM.addDisposableListener(element, EventType.Tap, e => this.onClick(e)));
|
||||
this._register(addDisposableListener(element, TouchEventType.Tap, e => this.onClick(e)));
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.MOUSE_DOWN, e => {
|
||||
this._register(addDisposableListener(element, EventType.MOUSE_DOWN, e => {
|
||||
if (!enableDragging) {
|
||||
DOM.EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||
EventHelper.stop(e, true); // do not run when dragging is on because that would disable it
|
||||
}
|
||||
|
||||
if (this._action.enabled && e.button === 0) {
|
||||
DOM.addClass(element, 'active');
|
||||
element.classList.add('active');
|
||||
}
|
||||
}));
|
||||
|
||||
|
@ -128,15 +128,15 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
|||
// main mouse button. This is for scenarios where e.g. some interaction forces
|
||||
// the Ctrl+key to be pressed and hold but the user still wants to interact
|
||||
// with the actions (for example quick access in quick navigation mode).
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CONTEXT_MENU, e => {
|
||||
this._register(addDisposableListener(element, EventType.CONTEXT_MENU, e => {
|
||||
if (e.button === 0 && e.ctrlKey === true) {
|
||||
this.onClick(e);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.CLICK, e => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this._register(addDisposableListener(element, EventType.CLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
|
||||
// menus do not use the click event
|
||||
if (!(this.options && this.options.isMenu)) {
|
||||
|
@ -144,20 +144,20 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
|||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(element, DOM.EventType.DBLCLICK, e => {
|
||||
DOM.EventHelper.stop(e, true);
|
||||
this._register(addDisposableListener(element, EventType.DBLCLICK, e => {
|
||||
EventHelper.stop(e, true);
|
||||
}));
|
||||
|
||||
[DOM.EventType.MOUSE_UP, DOM.EventType.MOUSE_OUT].forEach(event => {
|
||||
this._register(DOM.addDisposableListener(element, event, e => {
|
||||
DOM.EventHelper.stop(e);
|
||||
DOM.removeClass(element, 'active');
|
||||
[EventType.MOUSE_UP, EventType.MOUSE_OUT].forEach(event => {
|
||||
this._register(addDisposableListener(element, event, e => {
|
||||
EventHelper.stop(e);
|
||||
element.classList.remove('active');
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
onClick(event: DOM.EventLike): void {
|
||||
DOM.EventHelper.stop(event, true);
|
||||
onClick(event: EventLike): void {
|
||||
EventHelper.stop(event, true);
|
||||
|
||||
const context = types.isUndefinedOrNull(this._context) ? this.options?.useEventAsContext ? event : undefined : this._context;
|
||||
this.actionRunner.run(this._action, context);
|
||||
|
@ -166,14 +166,14 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
|||
focus(): void {
|
||||
if (this.element) {
|
||||
this.element.focus();
|
||||
DOM.addClass(this.element, 'focused');
|
||||
this.element.classList.add('focused');
|
||||
}
|
||||
}
|
||||
|
||||
blur(): void {
|
||||
if (this.element) {
|
||||
this.element.blur();
|
||||
DOM.removeClass(this.element, 'focused');
|
||||
this.element.classList.remove('focused');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ export class BaseActionViewItem extends Disposable implements IActionViewItem {
|
|||
|
||||
dispose(): void {
|
||||
if (this.element) {
|
||||
DOM.removeNode(this.element);
|
||||
this.element.remove();
|
||||
this.element = undefined;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
|||
super.render(container);
|
||||
|
||||
if (this.element) {
|
||||
this.label = DOM.append(this.element, DOM.$('a.action-label'));
|
||||
this.label = append(this.element, $('a.action-label'));
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
|
@ -249,7 +249,7 @@ export class ActionViewItem extends BaseActionViewItem {
|
|||
}
|
||||
|
||||
if (this.options.label && this.options.keybinding && this.element) {
|
||||
DOM.append(this.element, DOM.$('span.keybinding')).textContent = this.options.keybinding;
|
||||
append(this.element, $('span.keybinding')).textContent = this.options.keybinding;
|
||||
}
|
||||
|
||||
this.updateClass();
|
||||
|
@ -294,23 +294,23 @@ export class ActionViewItem extends BaseActionViewItem {
|
|||
|
||||
updateClass(): void {
|
||||
if (this.cssClass && this.label) {
|
||||
DOM.removeClasses(this.label, this.cssClass);
|
||||
removeClasses(this.label, this.cssClass);
|
||||
}
|
||||
|
||||
if (this.options.icon) {
|
||||
this.cssClass = this.getAction().class;
|
||||
|
||||
if (this.label) {
|
||||
DOM.addClass(this.label, 'codicon');
|
||||
this.label.classList.add('codicon');
|
||||
if (this.cssClass) {
|
||||
DOM.addClasses(this.label, this.cssClass);
|
||||
addClasses(this.label, this.cssClass);
|
||||
}
|
||||
}
|
||||
|
||||
this.updateEnabled();
|
||||
} else {
|
||||
if (this.label) {
|
||||
DOM.removeClass(this.label, 'codicon');
|
||||
this.label.classList.remove('codicon');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -319,22 +319,22 @@ export class ActionViewItem extends BaseActionViewItem {
|
|||
if (this.getAction().enabled) {
|
||||
if (this.label) {
|
||||
this.label.removeAttribute('aria-disabled');
|
||||
DOM.removeClass(this.label, 'disabled');
|
||||
this.label.classList.remove('disabled');
|
||||
this.label.tabIndex = 0;
|
||||
}
|
||||
|
||||
if (this.element) {
|
||||
DOM.removeClass(this.element, 'disabled');
|
||||
this.element.classList.remove('disabled');
|
||||
}
|
||||
} else {
|
||||
if (this.label) {
|
||||
this.label.setAttribute('aria-disabled', 'true');
|
||||
DOM.addClass(this.label, 'disabled');
|
||||
DOM.removeTabIndexAndUpdateFocus(this.label);
|
||||
this.label.classList.add('disabled');
|
||||
removeTabIndexAndUpdateFocus(this.label);
|
||||
}
|
||||
|
||||
if (this.element) {
|
||||
DOM.addClass(this.element, 'disabled');
|
||||
this.element.classList.add('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -342,9 +342,9 @@ export class ActionViewItem extends BaseActionViewItem {
|
|||
updateChecked(): void {
|
||||
if (this.label) {
|
||||
if (this.getAction().checked) {
|
||||
DOM.addClass(this.label, 'checked');
|
||||
this.label.classList.add('checked');
|
||||
} else {
|
||||
DOM.removeClass(this.label, 'checked');
|
||||
this.label.classList.remove('checked');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -475,7 +475,7 @@ export class ActionBar extends Disposable implements IActionRunner {
|
|||
|
||||
this._actionIds = [];
|
||||
|
||||
DOM.removeNode(this.getContainer());
|
||||
this.getContainer().remove();
|
||||
|
||||
super.dispose();
|
||||
}
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./button';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { mixin } from 'vs/base/common/objects';
|
||||
import { Event as BaseEvent, Emitter } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Gesture, EventType } from 'vs/base/browser/touch';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { Gesture, EventType as TouchEventType } from 'vs/base/browser/touch';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { addDisposableListener, IFocusTracker, EventType, EventHelper, trackFocus, reset, removeTabIndexAndUpdateFocus } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IButtonOptions extends IButtonStyles {
|
||||
readonly title?: boolean | string;
|
||||
|
@ -52,7 +52,7 @@ export class Button extends Disposable {
|
|||
private _onDidClick = this._register(new Emitter<Event>());
|
||||
get onDidClick(): BaseEvent<Event> { return this._onDidClick.event; }
|
||||
|
||||
private focusTracker: DOM.IFocusTracker;
|
||||
private focusTracker: IFocusTracker;
|
||||
|
||||
constructor(container: HTMLElement, options?: IButtonOptions) {
|
||||
super();
|
||||
|
@ -71,7 +71,7 @@ export class Button extends Disposable {
|
|||
this.buttonBorder = this.options.buttonBorder;
|
||||
|
||||
this._element = document.createElement('a');
|
||||
DOM.addClass(this._element, 'monaco-button');
|
||||
this._element.classList.add('monaco-button');
|
||||
this._element.tabIndex = 0;
|
||||
this._element.setAttribute('role', 'button');
|
||||
|
||||
|
@ -79,10 +79,10 @@ export class Button extends Disposable {
|
|||
|
||||
this._register(Gesture.addTarget(this._element));
|
||||
|
||||
[DOM.EventType.CLICK, EventType.Tap].forEach(eventType => {
|
||||
this._register(DOM.addDisposableListener(this._element, eventType, e => {
|
||||
[EventType.CLICK, TouchEventType.Tap].forEach(eventType => {
|
||||
this._register(addDisposableListener(this._element, eventType, e => {
|
||||
if (!this.enabled) {
|
||||
DOM.EventHelper.stop(e);
|
||||
EventHelper.stop(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ export class Button extends Disposable {
|
|||
}));
|
||||
});
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.KEY_DOWN, e => {
|
||||
this._register(addDisposableListener(this._element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = false;
|
||||
if (this.enabled && (event.equals(KeyCode.Enter) || event.equals(KeyCode.Space))) {
|
||||
|
@ -102,22 +102,22 @@ export class Button extends Disposable {
|
|||
}
|
||||
|
||||
if (eventHandled) {
|
||||
DOM.EventHelper.stop(event, true);
|
||||
EventHelper.stop(event, true);
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OVER, e => {
|
||||
if (!DOM.hasClass(this._element, 'disabled')) {
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OVER, e => {
|
||||
if (!this._element.classList.contains('disabled')) {
|
||||
this.setHoverBackground();
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(DOM.addDisposableListener(this._element, DOM.EventType.MOUSE_OUT, e => {
|
||||
this._register(addDisposableListener(this._element, EventType.MOUSE_OUT, e => {
|
||||
this.applyStyles(); // restore standard styles
|
||||
}));
|
||||
|
||||
// Also set hover background when button is focused for feedback
|
||||
this.focusTracker = this._register(DOM.trackFocus(this._element));
|
||||
this.focusTracker = this._register(trackFocus(this._element));
|
||||
this._register(this.focusTracker.onDidFocus(() => this.setHoverBackground()));
|
||||
this._register(this.focusTracker.onDidBlur(() => this.applyStyles())); // restore standard styles
|
||||
|
||||
|
@ -175,11 +175,9 @@ export class Button extends Disposable {
|
|||
}
|
||||
|
||||
set label(value: string) {
|
||||
if (!DOM.hasClass(this._element, 'monaco-text-button')) {
|
||||
DOM.addClass(this._element, 'monaco-text-button');
|
||||
}
|
||||
this._element.classList.add('monaco-text-button');
|
||||
if (this.options.supportCodicons) {
|
||||
DOM.reset(this._element, ...renderCodiconsAsElement(value));
|
||||
reset(this._element, ...renderCodicons(value));
|
||||
} else {
|
||||
this._element.textContent = value;
|
||||
}
|
||||
|
@ -191,23 +189,23 @@ export class Button extends Disposable {
|
|||
}
|
||||
|
||||
set icon(iconClassName: string) {
|
||||
DOM.addClass(this._element, iconClassName);
|
||||
this._element.classList.add(iconClassName);
|
||||
}
|
||||
|
||||
set enabled(value: boolean) {
|
||||
if (value) {
|
||||
DOM.removeClass(this._element, 'disabled');
|
||||
this._element.classList.remove('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(false));
|
||||
this._element.tabIndex = 0;
|
||||
} else {
|
||||
DOM.addClass(this._element, 'disabled');
|
||||
this._element.classList.add('disabled');
|
||||
this._element.setAttribute('aria-disabled', String(true));
|
||||
DOM.removeTabIndexAndUpdateFocus(this._element);
|
||||
removeTabIndexAndUpdateFocus(this._element);
|
||||
}
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return !DOM.hasClass(this._element, 'disabled');
|
||||
return !this._element.classList.contains('disabled');
|
||||
}
|
||||
|
||||
focus(): void {
|
||||
|
@ -235,7 +233,7 @@ export class ButtonGroup extends Disposable {
|
|||
|
||||
// Implement keyboard access in buttons if there are multiple
|
||||
if (count > 1) {
|
||||
this._register(DOM.addDisposableListener(button.element, DOM.EventType.KEY_DOWN, e => {
|
||||
this._register(addDisposableListener(button.element, EventType.KEY_DOWN, e => {
|
||||
const event = new StandardKeyboardEvent(e);
|
||||
let eventHandled = true;
|
||||
|
||||
|
@ -251,7 +249,7 @@ export class ButtonGroup extends Disposable {
|
|||
|
||||
if (eventHandled && typeof buttonIndexToFocus === 'number') {
|
||||
this._buttons[buttonIndexToFocus].focus();
|
||||
DOM.EventHelper.stop(e, true);
|
||||
EventHelper.stop(e, true);
|
||||
}
|
||||
|
||||
}));
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { reset } from 'vs/base/browser/dom';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export class CodiconLabel {
|
||||
|
||||
|
@ -13,7 +13,7 @@ export class CodiconLabel {
|
|||
) { }
|
||||
|
||||
set text(text: string) {
|
||||
reset(this._container, ...renderCodiconsAsElement(text ?? ''));
|
||||
reset(this._container, ...renderCodicons(text ?? ''));
|
||||
}
|
||||
|
||||
set title(title: string) {
|
||||
|
|
|
@ -139,7 +139,7 @@ export class ContextView extends Disposable {
|
|||
if (this.shadowRoot) {
|
||||
this.shadowRoot.removeChild(this.view);
|
||||
this.shadowRoot = null;
|
||||
DOM.removeNode(this.shadowRootHostElement!);
|
||||
this.shadowRootHostElement?.remove();
|
||||
this.shadowRootHostElement = null;
|
||||
} else {
|
||||
this.container.removeChild(this.view);
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
|
|||
import { IContextViewProvider, IAnchor, AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { EventHelper, EventType, removeClass, addClass, append, $, addDisposableListener, DOMEvent } from 'vs/base/browser/dom';
|
||||
import { EventHelper, EventType, append, $, addDisposableListener, DOMEvent } from 'vs/base/browser/dom';
|
||||
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
|
@ -162,7 +162,7 @@ export class Dropdown extends BaseDropdown {
|
|||
show(): void {
|
||||
super.show();
|
||||
|
||||
addClass(this.element, 'active');
|
||||
this.element.classList.add('active');
|
||||
|
||||
this.contextViewProvider.showContextView({
|
||||
getAnchor: () => this.getAnchor(),
|
||||
|
@ -184,7 +184,7 @@ export class Dropdown extends BaseDropdown {
|
|||
}
|
||||
|
||||
protected onHide(): void {
|
||||
removeClass(this.element, 'active');
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
|
||||
hide(): void {
|
||||
|
@ -253,7 +253,7 @@ export class DropdownMenu extends BaseDropdown {
|
|||
show(): void {
|
||||
super.show();
|
||||
|
||||
addClass(this.element, 'active');
|
||||
this.element.classList.add('active');
|
||||
|
||||
this._contextMenuProvider.showContextMenu({
|
||||
getAnchor: () => this.element,
|
||||
|
@ -275,6 +275,6 @@ export class DropdownMenu extends BaseDropdown {
|
|||
|
||||
private onHide(): void {
|
||||
this.hide();
|
||||
removeClass(this.element, 'active');
|
||||
this.element.classList.remove('active');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,11 @@ import { IAction, IActionRunner, IActionViewItemProvider } from 'vs/base/common/
|
|||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { append, $, addClasses } from 'vs/base/browser/dom';
|
||||
import { append, $ } from 'vs/base/browser/dom';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { BaseActionViewItem, IBaseActionViewItemOptions } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { IActionProvider, DropdownMenu, IDropdownMenuOptions, ILabelRenderer } from 'vs/base/browser/ui/dropdown/dropdown';
|
||||
import { IContextMenuProvider } from 'vs/base/browser/contextmenu';
|
||||
import { asArray } from 'vs/base/common/arrays';
|
||||
|
||||
export interface IKeybindingProvider {
|
||||
(action: IAction): ResolvedKeybinding | undefined;
|
||||
|
@ -60,14 +59,20 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
|
|||
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable | null => {
|
||||
this.element = append(el, $('a.action-label'));
|
||||
|
||||
const classNames = this.options.classNames ? asArray(this.options.classNames) : [];
|
||||
let classNames: string[] = [];
|
||||
|
||||
if (typeof this.options.classNames === 'string') {
|
||||
classNames = this.options.classNames.split(/\W+/g).filter(s => !!s);
|
||||
} else if (this.options.classNames) {
|
||||
classNames = this.options.classNames;
|
||||
}
|
||||
|
||||
// todo@aeschli: remove codicon, should come through `this.options.classNames`
|
||||
if (!classNames.find(c => c === 'icon')) {
|
||||
classNames.push('codicon');
|
||||
}
|
||||
|
||||
addClasses(this.element, ...classNames);
|
||||
this.element.classList.add(...classNames);
|
||||
|
||||
this.element.tabIndex = 0;
|
||||
this.element.setAttribute('role', 'button');
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import * as objects from 'vs/base/common/objects';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export interface IHighlight {
|
||||
start: number;
|
||||
|
@ -61,12 +61,12 @@ export class HighlightedLabel {
|
|||
}
|
||||
if (pos < highlight.start) {
|
||||
const substring = this.text.substring(pos, highlight.start);
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodiconsAsElement(substring) : [substring]));
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]));
|
||||
pos = highlight.end;
|
||||
}
|
||||
|
||||
const substring = this.text.substring(highlight.start, highlight.end);
|
||||
const element = dom.$('span.highlight', undefined, ...this.supportCodicons ? renderCodiconsAsElement(substring) : [substring]);
|
||||
const element = dom.$('span.highlight', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]);
|
||||
if (highlight.extraClasses) {
|
||||
element.classList.add(highlight.extraClasses);
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ export class HighlightedLabel {
|
|||
|
||||
if (pos < this.text.length) {
|
||||
const substring = this.text.substring(pos,);
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodiconsAsElement(substring) : [substring]));
|
||||
children.push(dom.$('span', undefined, ...this.supportCodicons ? renderCodicons(substring) : [substring]));
|
||||
}
|
||||
|
||||
dom.reset(this.domNode, ...children);
|
||||
|
|
|
@ -6,7 +6,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 * as DOM from 'vs/base/browser/dom';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
|
@ -22,6 +21,7 @@ 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';
|
||||
|
||||
interface IItem<T> {
|
||||
readonly id: string;
|
||||
|
@ -260,7 +260,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
this._horizontalScrolling = value;
|
||||
DOM.toggleClass(this.domNode, 'horizontal-scrolling', this._horizontalScrolling);
|
||||
this.domNode.classList.toggle('horizontal-scrolling', this._horizontalScrolling);
|
||||
|
||||
if (this._horizontalScrolling) {
|
||||
for (const item of this.items) {
|
||||
|
@ -268,7 +268,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
this.updateScrollWidth();
|
||||
this.scrollableElement.setScrollDimensions({ width: DOM.getContentWidth(this.domNode) });
|
||||
this.scrollableElement.setScrollDimensions({ width: getContentWidth(this.domNode) });
|
||||
this.rowsContainer.style.width = `${Math.max(this.scrollWidth || 0, this.renderWidth)}px`;
|
||||
} else {
|
||||
this.scrollableElementWidthDelayer.cancel();
|
||||
|
@ -303,13 +303,13 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
this.domNode = document.createElement('div');
|
||||
this.domNode.className = 'monaco-list';
|
||||
|
||||
DOM.addClass(this.domNode, this.domId);
|
||||
this.domNode.classList.add(this.domId);
|
||||
this.domNode.tabIndex = 0;
|
||||
|
||||
DOM.toggleClass(this.domNode, 'mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true);
|
||||
this.domNode.classList.toggle('mouse-support', typeof options.mouseSupport === 'boolean' ? options.mouseSupport : true);
|
||||
|
||||
this._horizontalScrolling = getOrDefault(options, o => o.horizontalScrolling, DefaultOptions.horizontalScrolling);
|
||||
DOM.toggleClass(this.domNode, 'horizontal-scrolling', this._horizontalScrolling);
|
||||
this.domNode.classList.toggle('horizontal-scrolling', this._horizontalScrolling);
|
||||
|
||||
this.additionalScrollHeight = typeof options.additionalScrollHeight === 'undefined' ? 0 : options.additionalScrollHeight;
|
||||
|
||||
|
@ -325,7 +325,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
this.disposables.add(Gesture.addTarget(this.rowsContainer));
|
||||
|
||||
this.scrollable = new Scrollable(getOrDefault(options, o => o.smoothScrolling, false) ? 125 : 0, cb => DOM.scheduleAtNextAnimationFrame(cb));
|
||||
this.scrollable = new Scrollable(getOrDefault(options, o => o.smoothScrolling, false) ? 125 : 0, cb => scheduleAtNextAnimationFrame(cb));
|
||||
this.scrollableElement = this.disposables.add(new SmoothScrollableElement(this.rowsContainer, {
|
||||
alwaysConsumeMouseWheel: true,
|
||||
horizontal: ScrollbarVisibility.Auto,
|
||||
|
@ -510,7 +510,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
this.rowsContainer.style.height = `${this._scrollHeight}px`;
|
||||
|
||||
if (!this.scrollableElementUpdateDisposable) {
|
||||
this.scrollableElementUpdateDisposable = DOM.scheduleAtNextAnimationFrame(() => {
|
||||
this.scrollableElementUpdateDisposable = scheduleAtNextAnimationFrame(() => {
|
||||
this.scrollableElement.setScrollDimensions({ scrollHeight: this.scrollHeight });
|
||||
this.updateScrollWidth();
|
||||
this.scrollableElementUpdateDisposable = null;
|
||||
|
@ -629,7 +629,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
layout(height?: number, width?: number): void {
|
||||
let scrollDimensions: INewScrollDimensions = {
|
||||
height: typeof height === 'number' ? height : DOM.getContentHeight(this.domNode)
|
||||
height: typeof height === 'number' ? height : getContentHeight(this.domNode)
|
||||
};
|
||||
|
||||
if (this.scrollableElementUpdateDisposable) {
|
||||
|
@ -649,7 +649,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
if (this.horizontalScrolling) {
|
||||
this.scrollableElement.setScrollDimensions({
|
||||
width: typeof width === 'number' ? width : DOM.getContentWidth(this.domNode)
|
||||
width: typeof width === 'number' ? width : getContentWidth(this.domNode)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -754,7 +754,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
}
|
||||
|
||||
item.row.domNode.style.width = isFirefox ? '-moz-fit-content' : 'fit-content';
|
||||
item.width = DOM.getContentWidth(item.row.domNode);
|
||||
item.width = getContentWidth(item.row.domNode);
|
||||
const style = window.getComputedStyle(item.row.domNode);
|
||||
|
||||
if (style.paddingLeft) {
|
||||
|
@ -785,7 +785,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
item.row!.domNode!.setAttribute('aria-posinset', String(this.accessibilityProvider.getPosInSet(item.element, index)));
|
||||
item.row!.domNode!.setAttribute('id', this.getElementDomId(index));
|
||||
|
||||
DOM.toggleClass(item.row!.domNode!, 'drop-target', item.dropTarget);
|
||||
item.row!.domNode!.classList.toggle('drop-target', item.dropTarget);
|
||||
}
|
||||
|
||||
private removeItemFromDOM(index: number): void {
|
||||
|
@ -936,7 +936,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
label = String(elements.length);
|
||||
}
|
||||
|
||||
const dragImage = DOM.$('.monaco-drag-image');
|
||||
const dragImage = $('.monaco-drag-image');
|
||||
dragImage.textContent = label;
|
||||
document.body.appendChild(dragImage);
|
||||
event.dataTransfer.setDragImage(dragImage, -10, -10);
|
||||
|
@ -1017,11 +1017,11 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
this.currentDragFeedbackDisposable.dispose();
|
||||
|
||||
if (feedback[0] === -1) { // entire list feedback
|
||||
DOM.addClass(this.domNode, 'drop-target');
|
||||
DOM.addClass(this.rowsContainer, 'drop-target');
|
||||
this.domNode.classList.add('drop-target');
|
||||
this.rowsContainer.classList.add('drop-target');
|
||||
this.currentDragFeedbackDisposable = toDisposable(() => {
|
||||
DOM.removeClass(this.domNode, 'drop-target');
|
||||
DOM.removeClass(this.rowsContainer, 'drop-target');
|
||||
this.domNode.classList.remove('drop-target');
|
||||
this.rowsContainer.classList.remove('drop-target');
|
||||
});
|
||||
} else {
|
||||
for (const index of feedback) {
|
||||
|
@ -1029,7 +1029,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
item.dropTarget = true;
|
||||
|
||||
if (item.row && item.row.domNode) {
|
||||
DOM.addClass(item.row.domNode, 'drop-target');
|
||||
item.row.domNode.classList.add('drop-target');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1039,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
item.dropTarget = false;
|
||||
|
||||
if (item.row && item.row.domNode) {
|
||||
DOM.removeClass(item.row.domNode, 'drop-target');
|
||||
item.row.domNode.classList.remove('drop-target');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1095,8 +1095,8 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
|
|||
|
||||
private setupDragAndDropScrollTopAnimation(event: DragEvent): void {
|
||||
if (!this.dragOverAnimationDisposable) {
|
||||
const viewTop = DOM.getTopLeftOffset(this.domNode).top;
|
||||
this.dragOverAnimationDisposable = DOM.animate(this.animateDragAndDropScrollTop.bind(this, viewTop));
|
||||
const viewTop = getTopLeftOffset(this.domNode).top;
|
||||
this.dragOverAnimationDisposable = animate(this.animateDragAndDropScrollTop.bind(this, viewTop));
|
||||
}
|
||||
|
||||
this.dragOverAnimationStopDisposable.dispose();
|
||||
|
|
|
@ -8,7 +8,6 @@ import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle'
|
|||
import { isNumber } from 'vs/base/common/types';
|
||||
import { range, binarySearch } from 'vs/base/common/arrays';
|
||||
import { memoize } from 'vs/base/common/decorators';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { Gesture } from 'vs/base/browser/touch';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
|
@ -27,6 +26,7 @@ import { matchesPrefix } from 'vs/base/common/filters';
|
|||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
import { createStyleSheet } from 'vs/base/browser/dom';
|
||||
|
||||
interface ITraitChangeEvent {
|
||||
indexes: number[];
|
||||
|
@ -137,11 +137,11 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
|
|||
}
|
||||
|
||||
renderIndex(index: number, container: HTMLElement): void {
|
||||
DOM.toggleClass(container, this._trait, this.contains(index));
|
||||
container.classList.toggle(this._trait, this.contains(index));
|
||||
}
|
||||
|
||||
unrender(container: HTMLElement): void {
|
||||
DOM.removeClass(container, this._trait);
|
||||
container.classList.remove(this._trait);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -230,11 +230,11 @@ export function isInputElement(e: HTMLElement): boolean {
|
|||
}
|
||||
|
||||
export function isMonacoEditor(e: HTMLElement): boolean {
|
||||
if (DOM.hasClass(e, 'monaco-editor')) {
|
||||
if (e.classList.contains('monaco-editor')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (DOM.hasClass(e, 'monaco-list')) {
|
||||
if (e.classList.contains('monaco-list')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1225,7 +1225,7 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
|||
if (_options.styleController) {
|
||||
this.styleController = _options.styleController(this.view.domId);
|
||||
} else {
|
||||
const styleElement = DOM.createStyleSheet(this.view.domNode);
|
||||
const styleElement = createStyleSheet(this.view.domNode);
|
||||
this.styleController = new DefaultStyleController(styleElement, this.view.domId);
|
||||
}
|
||||
|
||||
|
@ -1633,7 +1633,7 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
|||
|
||||
private _onFocusChange(): void {
|
||||
const focus = this.focus.get();
|
||||
DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0);
|
||||
this.view.domNode.classList.toggle('element-focused', focus.length > 0);
|
||||
this.onDidChangeActiveDescendant();
|
||||
}
|
||||
|
||||
|
@ -1656,9 +1656,9 @@ export class List<T> implements ISpliceable<T>, IThemable, IDisposable {
|
|||
private _onSelectionChange(): void {
|
||||
const selection = this.selection.get();
|
||||
|
||||
DOM.toggleClass(this.view.domNode, 'selection-none', selection.length === 0);
|
||||
DOM.toggleClass(this.view.domNode, 'selection-single', selection.length === 1);
|
||||
DOM.toggleClass(this.view.domNode, 'selection-multiple', selection.length > 1);
|
||||
this.view.domNode.classList.toggle('selection-none', selection.length === 0);
|
||||
this.view.domNode.classList.toggle('selection-single', selection.length === 1);
|
||||
this.view.domNode.classList.toggle('selection-multiple', selection.length > 1);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { IListRenderer } from './list';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { $, removeClass } from 'vs/base/browser/dom';
|
||||
import { $ } from 'vs/base/browser/dom';
|
||||
|
||||
export interface IRow {
|
||||
domNode: HTMLElement | null;
|
||||
|
@ -60,7 +60,7 @@ export class RowCache<T> implements IDisposable {
|
|||
private releaseRow(row: IRow): void {
|
||||
const { domNode, templateId } = row;
|
||||
if (domNode) {
|
||||
removeClass(domNode, 'scrolling');
|
||||
domNode.classList.remove('scrolling');
|
||||
removeFromParent(domNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as types from 'vs/base/common/types';
|
|||
import { EventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom';
|
||||
import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $ } from 'vs/base/browser/dom';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
|
||||
const DEBUG = false;
|
||||
|
@ -86,9 +86,9 @@ export class Sash extends Disposable {
|
|||
return;
|
||||
}
|
||||
|
||||
toggleClass(this.el, 'disabled', state === SashState.Disabled);
|
||||
toggleClass(this.el, 'minimum', state === SashState.Minimum);
|
||||
toggleClass(this.el, 'maximum', state === SashState.Maximum);
|
||||
this.el.classList.toggle('disabled', state === SashState.Disabled);
|
||||
this.el.classList.toggle('minimum', state === SashState.Minimum);
|
||||
this.el.classList.toggle('maximum', state === SashState.Maximum);
|
||||
|
||||
this._state = state;
|
||||
this._onDidEnablementChange.fire(state);
|
||||
|
@ -151,7 +151,7 @@ export class Sash extends Disposable {
|
|||
this.el = append(container, $('.monaco-sash'));
|
||||
|
||||
if (isMacintosh) {
|
||||
addClass(this.el, 'mac');
|
||||
this.el.classList.add('mac');
|
||||
}
|
||||
|
||||
this._register(domEvent(this.el, 'mousedown')(this.onMouseDown, this));
|
||||
|
@ -185,14 +185,14 @@ export class Sash extends Disposable {
|
|||
this.orientation = options.orientation || Orientation.VERTICAL;
|
||||
|
||||
if (this.orientation === Orientation.HORIZONTAL) {
|
||||
addClass(this.el, 'horizontal');
|
||||
removeClass(this.el, 'vertical');
|
||||
this.el.classList.add('horizontal');
|
||||
this.el.classList.remove('vertical');
|
||||
} else {
|
||||
removeClass(this.el, 'horizontal');
|
||||
addClass(this.el, 'vertical');
|
||||
this.el.classList.remove('horizontal');
|
||||
this.el.classList.add('vertical');
|
||||
}
|
||||
|
||||
toggleClass(this.el, 'debug', DEBUG);
|
||||
this.el.classList.toggle('debug', DEBUG);
|
||||
|
||||
this.layout();
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ export class Sash extends Disposable {
|
|||
const altKey = mouseDownEvent.altKey;
|
||||
const startEvent: ISashEvent = { startX, currentX: startX, startY, currentY: startY, altKey };
|
||||
|
||||
addClass(this.el, 'active');
|
||||
this.el.classList.add('active');
|
||||
this._onDidStart.fire(startEvent);
|
||||
|
||||
// fix https://github.com/Microsoft/vscode/issues/21675
|
||||
|
@ -290,7 +290,7 @@ export class Sash extends Disposable {
|
|||
|
||||
this.el.removeChild(style);
|
||||
|
||||
removeClass(this.el, 'active');
|
||||
this.el.classList.remove('active');
|
||||
this._onDidEnd.fire();
|
||||
|
||||
disposables.dispose();
|
||||
|
@ -396,11 +396,11 @@ export class Sash extends Disposable {
|
|||
}
|
||||
|
||||
private onOrthogonalStartSashEnablementChange(state: SashState): void {
|
||||
toggleClass(this.el, 'orthogonal-start', state !== SashState.Disabled);
|
||||
this.el.classList.toggle('orthogonal-start', state !== SashState.Disabled);
|
||||
}
|
||||
|
||||
private onOrthogonalEndSashEnablementChange(state: SashState): void {
|
||||
toggleClass(this.el, 'orthogonal-end', state !== SashState.Disabled);
|
||||
this.el.classList.toggle('orthogonal-end', state !== SashState.Disabled);
|
||||
}
|
||||
|
||||
private getOrthogonalSash(e: MouseEvent): Sash | undefined {
|
||||
|
|
|
@ -9,7 +9,7 @@ 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, addClass, removeClass, toggleClass, trackFocus, EventHelper, clearNode } from 'vs/base/browser/dom';
|
||||
import { $, append, trackFocus, EventHelper, clearNode } 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';
|
||||
|
@ -142,7 +142,7 @@ export abstract class Pane extends Disposable implements IView {
|
|||
}
|
||||
|
||||
if (this.element) {
|
||||
toggleClass(this.element, 'expanded', expanded);
|
||||
this.element.classList.toggle('expanded', expanded);
|
||||
}
|
||||
|
||||
this._expanded = !!expanded;
|
||||
|
@ -190,8 +190,8 @@ export abstract class Pane extends Disposable implements IView {
|
|||
this._orientation = orientation;
|
||||
|
||||
if (this.element) {
|
||||
toggleClass(this.element, 'horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
toggleClass(this.element, 'vertical', this.orientation === Orientation.VERTICAL);
|
||||
this.element.classList.toggle('horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
this.element.classList.toggle('vertical', this.orientation === Orientation.VERTICAL);
|
||||
}
|
||||
|
||||
if (this.header) {
|
||||
|
@ -200,9 +200,9 @@ export abstract class Pane extends Disposable implements IView {
|
|||
}
|
||||
|
||||
render(): void {
|
||||
toggleClass(this.element, 'expanded', this.isExpanded());
|
||||
toggleClass(this.element, 'horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
toggleClass(this.element, 'vertical', this.orientation === Orientation.VERTICAL);
|
||||
this.element.classList.toggle('expanded', this.isExpanded());
|
||||
this.element.classList.toggle('horizontal', this.orientation === Orientation.HORIZONTAL);
|
||||
this.element.classList.toggle('vertical', this.orientation === Orientation.VERTICAL);
|
||||
|
||||
this.header = $('.pane-header');
|
||||
append(this.element, this.header);
|
||||
|
@ -214,8 +214,8 @@ export abstract class Pane extends Disposable implements IView {
|
|||
|
||||
const focusTracker = trackFocus(this.header);
|
||||
this._register(focusTracker);
|
||||
this._register(focusTracker.onDidFocus(() => addClass(this.header, 'focused'), null));
|
||||
this._register(focusTracker.onDidBlur(() => removeClass(this.header, 'focused'), null));
|
||||
this._register(focusTracker.onDidFocus(() => this.header.classList.add('focused'), null));
|
||||
this._register(focusTracker.onDidBlur(() => this.header.classList.remove('focused'), null));
|
||||
|
||||
this.updateHeader();
|
||||
|
||||
|
@ -254,7 +254,7 @@ export abstract class Pane extends Disposable implements IView {
|
|||
const height = this._orientation === Orientation.VERTICAL ? size - headerSize : this.orthogonalSize - headerSize;
|
||||
|
||||
if (this.isExpanded()) {
|
||||
toggleClass(this.body, 'wide', width >= 600);
|
||||
this.body.classList.toggle('wide', width >= 600);
|
||||
this.layoutBody(height, width);
|
||||
this.expandedSize = size;
|
||||
}
|
||||
|
@ -274,8 +274,8 @@ export abstract class Pane extends Disposable implements IView {
|
|||
const expanded = !this.headerVisible || this.isExpanded();
|
||||
|
||||
this.header.style.lineHeight = `${this.headerSize}px`;
|
||||
toggleClass(this.header, 'hidden', !this.headerVisible);
|
||||
toggleClass(this.header, 'expanded', expanded);
|
||||
this.header.classList.toggle('hidden', !this.headerVisible);
|
||||
this.header.classList.toggle('expanded', expanded);
|
||||
this.header.setAttribute('aria-expanded', String(expanded));
|
||||
|
||||
this.header.style.color = this.styles.headerForeground ? this.styles.headerForeground.toString() : '';
|
||||
|
@ -560,11 +560,11 @@ export class PaneView extends Disposable {
|
|||
window.clearTimeout(this.animationTimer);
|
||||
}
|
||||
|
||||
addClass(this.el, 'animated');
|
||||
this.el.classList.add('animated');
|
||||
|
||||
this.animationTimer = window.setTimeout(() => {
|
||||
this.animationTimer = undefined;
|
||||
removeClass(this.el, 'animated');
|
||||
this.el.classList.remove('animated');
|
||||
}, 200);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,12 +7,12 @@ import 'vs/css!./splitview';
|
|||
import { IDisposable, toDisposable, Disposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
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 } from 'vs/base/browser/dom';
|
||||
export { Orientation } from 'vs/base/browser/ui/sash/sash';
|
||||
|
||||
export interface ISplitViewStyles {
|
||||
|
@ -93,7 +93,7 @@ abstract class ViewItem<TLayoutContext> {
|
|||
this.size = 0;
|
||||
}
|
||||
|
||||
dom.toggleClass(this.container, 'visible', visible);
|
||||
this.container.classList.toggle('visible', visible);
|
||||
|
||||
if (this.view.setVisible) {
|
||||
this.view.setVisible(visible);
|
||||
|
@ -122,7 +122,7 @@ abstract class ViewItem<TLayoutContext> {
|
|||
if (typeof size === 'number') {
|
||||
this._size = size;
|
||||
this._cachedVisibleSize = undefined;
|
||||
dom.addClass(container, 'visible');
|
||||
container.classList.add('visible');
|
||||
} else {
|
||||
this._size = 0;
|
||||
this._cachedVisibleSize = size.cachedVisibleSize;
|
||||
|
@ -296,12 +296,12 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
|||
this.proportionalLayout = types.isUndefined(options.proportionalLayout) ? true : !!options.proportionalLayout;
|
||||
|
||||
this.el = document.createElement('div');
|
||||
dom.addClass(this.el, 'monaco-split-view2');
|
||||
dom.addClass(this.el, this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
|
||||
this.el.classList.add('monaco-split-view2');
|
||||
this.el.classList.add(this.orientation === Orientation.VERTICAL ? 'vertical' : 'horizontal');
|
||||
container.appendChild(this.el);
|
||||
|
||||
this.sashContainer = dom.append(this.el, dom.$('.sash-container'));
|
||||
this.viewContainer = dom.append(this.el, dom.$('.split-view-container'));
|
||||
this.sashContainer = append(this.el, $('.sash-container'));
|
||||
this.viewContainer = append(this.el, $('.split-view-container'));
|
||||
|
||||
this.style(options.styles || defaultStyles);
|
||||
|
||||
|
@ -323,10 +323,10 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
|||
|
||||
style(styles: ISplitViewStyles): void {
|
||||
if (styles.separatorBorder.isTransparent()) {
|
||||
dom.removeClass(this.el, 'separator-border');
|
||||
this.el.classList.remove('separator-border');
|
||||
this.el.style.removeProperty('--separator-border');
|
||||
} else {
|
||||
dom.addClass(this.el, 'separator-border');
|
||||
this.el.classList.add('separator-border');
|
||||
this.el.style.setProperty('--separator-border', styles.separatorBorder.toString());
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ export class SplitView<TLayoutContext = undefined> extends Disposable {
|
|||
this.state = State.Busy;
|
||||
|
||||
// Add view
|
||||
const container = dom.$('.split-view-view');
|
||||
const container = $('.split-view-view');
|
||||
|
||||
if (index === this.viewItems.length) {
|
||||
this.viewContainer.appendChild(container);
|
||||
|
|
|
@ -72,7 +72,7 @@ export class ToolBar extends Disposable {
|
|||
actionViewItemProvider: this.options.actionViewItemProvider,
|
||||
actionRunner: this.actionRunner,
|
||||
keybindingProvider: this.options.getKeyBinding,
|
||||
classNames: toolBarMoreIcon.classNames,
|
||||
classNames: toolBarMoreIcon.classNamesArray,
|
||||
anchorAlignmentProvider: this.options.anchorAlignmentProvider,
|
||||
menuAsChild: !!this.options.renderDropdownAsChildElement
|
||||
}
|
||||
|
|
|
@ -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, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode, addClasses, removeClasses } from 'vs/base/browser/dom';
|
||||
import { append, $, getDomNodePagePosition, hasParentWithClass, createStyleSheet, clearNode } 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';
|
||||
|
@ -405,10 +405,10 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
|||
}
|
||||
|
||||
if (node.collapsible && (!this.hideTwistiesOfChildlessElements || node.visibleChildrenCount > 0)) {
|
||||
addClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible');
|
||||
toggleClass(templateData.twistie, 'collapsed', node.collapsed);
|
||||
templateData.twistie.classList.add(...treeItemExpandedIcon.classNamesArray, 'collapsible');
|
||||
templateData.twistie.classList.toggle('collapsed', node.collapsed);
|
||||
} else {
|
||||
removeClasses(templateData.twistie, treeItemExpandedIcon.classNames, 'collapsible', 'collapsed');
|
||||
templateData.twistie.classList.remove(...treeItemExpandedIcon.classNamesArray, 'collapsible', 'collapsed');
|
||||
}
|
||||
|
||||
if (node.collapsible) {
|
||||
|
@ -443,7 +443,7 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
|||
const guide = $<HTMLDivElement>('.indent-guide', { style: `width: ${this.indent}px` });
|
||||
|
||||
if (this.activeIndentNodes.has(parent)) {
|
||||
addClass(guide, 'active');
|
||||
guide.classList.add('active');
|
||||
}
|
||||
|
||||
if (templateData.indent.childElementCount === 0) {
|
||||
|
@ -486,13 +486,13 @@ class TreeRenderer<T, TFilterData, TRef, TTemplateData> implements IListRenderer
|
|||
|
||||
this.activeIndentNodes.forEach(node => {
|
||||
if (!set.has(node)) {
|
||||
this.renderedIndentGuides.forEach(node, line => removeClass(line, 'active'));
|
||||
this.renderedIndentGuides.forEach(node, line => line.classList.remove('active'));
|
||||
}
|
||||
});
|
||||
|
||||
set.forEach(node => {
|
||||
if (!this.activeIndentNodes.has(node)) {
|
||||
this.renderedIndentGuides.forEach(node, line => addClass(line, 'active'));
|
||||
this.renderedIndentGuides.forEach(node, line => line.classList.add('active'));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -833,10 +833,10 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
|||
};
|
||||
|
||||
updatePosition();
|
||||
removeClass(this.domNode, positionClassName);
|
||||
this.domNode.classList.remove(positionClassName);
|
||||
|
||||
addClass(this.domNode, 'dragging');
|
||||
disposables.add(toDisposable(() => removeClass(this.domNode, 'dragging')));
|
||||
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);
|
||||
|
@ -864,12 +864,12 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
|||
|
||||
private updateFilterOnTypeTitleAndIcon(): void {
|
||||
if (this.filterOnType) {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOffIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOnIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.title = localize('disable filter on type', "Disable Filter on Type");
|
||||
} else {
|
||||
removeClasses(this.filterOnTypeDomNode, treeFilterOnTypeOnIcon.classNames);
|
||||
addClasses(this.filterOnTypeDomNode, treeFilterOnTypeOffIcon.classNames);
|
||||
this.filterOnTypeDomNode.classList.remove(...treeFilterOnTypeOnIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.classList.add(...treeFilterOnTypeOffIcon.classNamesArray);
|
||||
this.filterOnTypeDomNode.title = localize('enable filter on type', "Enable Filter on Type");
|
||||
}
|
||||
}
|
||||
|
@ -885,7 +885,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
|
|||
this._empty = false;
|
||||
}
|
||||
|
||||
toggleClass(this.domNode, 'no-matches', noMatches);
|
||||
this.domNode.classList.toggle('no-matches', noMatches);
|
||||
this.domNode.title = localize('found', "Matched {0} out of {1} elements", this.filter.matchCount, this.filter.totalCount);
|
||||
this.labelDomNode.textContent = this.pattern.length > 16 ? '…' + this.pattern.substr(this.pattern.length - 16) : this.pattern;
|
||||
|
||||
|
@ -1096,8 +1096,8 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
|||
}
|
||||
|
||||
const target = e.browserEvent.target as HTMLElement;
|
||||
const onTwistie = hasClass(target, 'monaco-tl-twistie')
|
||||
|| (hasClass(target, 'monaco-icon-label') && hasClass(target, 'folder-icon') && e.browserEvent.offsetX < 16);
|
||||
const onTwistie = target.classList.contains('monaco-tl-twistie')
|
||||
|| (target.classList.contains('monaco-icon-label') && target.classList.contains('folder-icon') && e.browserEvent.offsetX < 16);
|
||||
|
||||
let expandOnlyOnTwistieClick = false;
|
||||
|
||||
|
@ -1130,7 +1130,7 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
|
|||
}
|
||||
|
||||
protected onDoubleClick(e: IListMouseEvent<ITreeNode<T, TFilterData>>): void {
|
||||
const onTwistie = hasClass(e.browserEvent.target as HTMLElement, 'monaco-tl-twistie');
|
||||
const onTwistie = (e.browserEvent.target as HTMLElement).classList.contains('monaco-tl-twistie');
|
||||
|
||||
if (onTwistie) {
|
||||
return;
|
||||
|
@ -1340,7 +1340,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
}
|
||||
|
||||
this.styleElement = createStyleSheet(this.view.getHTMLElement());
|
||||
toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
}
|
||||
|
||||
updateOptions(optionsUpdate: IAbstractTreeOptionsUpdate = {}): void {
|
||||
|
@ -1363,7 +1363,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
|
|||
|
||||
this._onDidUpdateOptions.fire(this._options);
|
||||
|
||||
toggleClass(this.getHTMLElement(), 'always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
this.getHTMLElement().classList.toggle('always', this._options.renderIndentGuides === RenderIndentGuides.Always);
|
||||
}
|
||||
|
||||
get options(): IAbstractTreeOptions<T, TFilterData> {
|
||||
|
|
|
@ -15,7 +15,6 @@ import { Iterable } from 'vs/base/common/iterator';
|
|||
import { IDragAndDropData } from 'vs/base/browser/dnd';
|
||||
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
|
||||
import { isPromiseCanceledError, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { removeClasses, addClasses } from 'vs/base/browser/dom';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
|
@ -110,9 +109,9 @@ class AsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> implements IT
|
|||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.add(...treeItemLoadingIcon.classNamesArray);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.remove(...treeItemLoadingIcon.classNamesArray);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1053,9 +1052,9 @@ class CompressibleAsyncDataTreeRenderer<TInput, T, TFilterData, TTemplateData> i
|
|||
|
||||
renderTwistie(element: IAsyncDataTreeNode<TInput, T>, twistieElement: HTMLElement): boolean {
|
||||
if (element.slow) {
|
||||
addClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.add(...treeItemLoadingIcon.classNamesArray);
|
||||
} else {
|
||||
removeClasses(twistieElement, treeItemLoadingIcon.classNames);
|
||||
twistieElement.classList.remove(...treeItemLoadingIcon.classNamesArray);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -618,10 +618,10 @@ export class RunOnceScheduler {
|
|||
private timeout: number;
|
||||
private timeoutHandler: () => void;
|
||||
|
||||
constructor(runner: (...args: any[]) => void, timeout: number) {
|
||||
constructor(runner: (...args: any[]) => void, delay: number) {
|
||||
this.timeoutToken = -1;
|
||||
this.runner = runner;
|
||||
this.timeout = timeout;
|
||||
this.timeout = delay;
|
||||
this.timeoutHandler = this.onTimeout.bind(this);
|
||||
}
|
||||
|
||||
|
@ -651,6 +651,14 @@ export class RunOnceScheduler {
|
|||
this.timeoutToken = setTimeout(this.timeoutHandler, delay);
|
||||
}
|
||||
|
||||
get delay(): number {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
set delay(value: number) {
|
||||
this.timeout = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if scheduled.
|
||||
*/
|
||||
|
|
|
@ -501,20 +501,6 @@ export function markdownUnescapeCodicons(text: string): string {
|
|||
return text.replace(markdownUnescapeCodiconsRegex, (match, escaped, codicon) => escaped ? match : `$(${codicon})`);
|
||||
}
|
||||
|
||||
export const renderCodiconsRegex = /(\\)?\$\((([a-z0-9\-]+?)(?:~([a-z0-9\-]*?))?)\)/gi;
|
||||
|
||||
/**
|
||||
* @deprecated Use `renderCodiconsAsElement` instead
|
||||
*/
|
||||
export function renderCodicons(text: string): string {
|
||||
return text.replace(renderCodiconsRegex, (_, escaped, codicon, name, animation) => {
|
||||
// If the class for codicons is changed, it should also be updated in src\vs\base\browser\markdownRenderer.ts
|
||||
return escaped
|
||||
? `$(${codicon})`
|
||||
: `<span class="codicon codicon-${name}${animation ? ` codicon-animation-${animation}` : ''}"></span>`;
|
||||
});
|
||||
}
|
||||
|
||||
const stripCodiconsRegex = /(\s)?(\\)?\$\([a-z0-9\-]+?(?:~[a-z0-9\-]*?)?\)(\s)?/gi;
|
||||
export function stripCodicons(text: string): string {
|
||||
if (text.indexOf(codiconStartMarker) === -1) {
|
||||
|
|
|
@ -12,7 +12,6 @@ export function hash(obj: any): number {
|
|||
return doHash(obj, 0);
|
||||
}
|
||||
|
||||
|
||||
export function doHash(obj: any, hashVal: number): number {
|
||||
switch (typeof obj) {
|
||||
case 'object':
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { ChildProcess, fork, ForkOptions } from 'child_process';
|
||||
import { IDisposable, toDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { Delayer, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { deepClone, assign } from 'vs/base/common/objects';
|
||||
import { deepClone } from 'vs/base/common/objects';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { createQueuedSender } from 'vs/base/node/processes';
|
||||
import { IChannel, ChannelServer as IPCServer, ChannelClient as IPCClient, IChannelClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
|
@ -180,10 +180,10 @@ export class Client implements IChannelClient, IDisposable {
|
|||
const args = this.options && this.options.args ? this.options.args : [];
|
||||
const forkOpts: ForkOptions = Object.create(null);
|
||||
|
||||
forkOpts.env = assign(deepClone(process.env), { 'VSCODE_PARENT_PID': String(process.pid) });
|
||||
forkOpts.env = { ...deepClone(process.env), 'VSCODE_PARENT_PID': String(process.pid) };
|
||||
|
||||
if (this.options && this.options.env) {
|
||||
forkOpts.env = assign(forkOpts.env, this.options.env);
|
||||
forkOpts.env = { ...forkOpts.env, ...this.options.env };
|
||||
}
|
||||
|
||||
if (this.options && this.options.freshExecArgv) {
|
||||
|
|
|
@ -3,43 +3,43 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import * as assert from 'assert';
|
||||
|
||||
suite('renderCodicons', () => {
|
||||
|
||||
test('no codicons', () => {
|
||||
const result = renderCodiconsAsElement(' hello World .');
|
||||
const result = renderCodicons(' hello World .');
|
||||
|
||||
assert.equal(elementsToString(result), ' hello World .');
|
||||
});
|
||||
|
||||
test('codicon only', () => {
|
||||
const result = renderCodiconsAsElement('$(alert)');
|
||||
const result = renderCodicons('$(alert)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-alert"></span>');
|
||||
});
|
||||
|
||||
test('codicon and non-codicon strings', () => {
|
||||
const result = renderCodiconsAsElement(` $(alert) Unresponsive`);
|
||||
const result = renderCodicons(` $(alert) Unresponsive`);
|
||||
|
||||
assert.equal(elementsToString(result), ' <span class="codicon codicon-alert"></span> Unresponsive');
|
||||
});
|
||||
|
||||
test('multiple codicons', () => {
|
||||
const result = renderCodiconsAsElement('$(check)$(error)');
|
||||
const result = renderCodicons('$(check)$(error)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-check"></span><span class="codicon codicon-error"></span>');
|
||||
});
|
||||
|
||||
test('escaped codicon', () => {
|
||||
const result = renderCodiconsAsElement('\\$(escaped)');
|
||||
const result = renderCodicons('\\$(escaped)');
|
||||
|
||||
assert.equal(elementsToString(result), '$(escaped)');
|
||||
});
|
||||
|
||||
test('codicon with animation', () => {
|
||||
const result = renderCodiconsAsElement('$(zip~anim)');
|
||||
const result = renderCodicons('$(zip~anim)');
|
||||
|
||||
assert.equal(elementsToString(result), '<span class="codicon codicon-zip codicon-animation-anim"></span>');
|
||||
});
|
||||
|
|
|
@ -7,7 +7,6 @@ import * as assert from 'assert';
|
|||
import { ITreeNode, ITreeRenderer, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||
import { AsyncDataTree } from 'vs/base/browser/ui/tree/asyncDataTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { hasClass } from 'vs/base/browser/dom';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
|
||||
interface Element {
|
||||
|
@ -103,8 +102,8 @@ suite('AsyncDataTree', function () {
|
|||
await tree.setInput(model.root);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [
|
||||
{ id: 'aa' },
|
||||
|
@ -151,8 +150,8 @@ suite('AsyncDataTree', function () {
|
|||
assert.deepStrictEqual(getChildrenCalls, ['root']);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
|
@ -160,8 +159,8 @@ suite('AsyncDataTree', function () {
|
|||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [];
|
||||
|
@ -169,8 +168,8 @@ suite('AsyncDataTree', function () {
|
|||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }, { id: 'ab' }, { id: 'ac' }];
|
||||
|
@ -178,8 +177,8 @@ suite('AsyncDataTree', function () {
|
|||
|
||||
assert.deepStrictEqual(getChildrenCalls, ['root', 'root', 'root', 'root']);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode().children[0].collapsed);
|
||||
});
|
||||
|
||||
|
@ -241,8 +240,8 @@ suite('AsyncDataTree', function () {
|
|||
await tree.expand(model.get('a'));
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(!tree.getNode(model.get('a')).collapsed);
|
||||
|
||||
tree.collapse(model.get('a'));
|
||||
|
@ -250,8 +249,8 @@ suite('AsyncDataTree', function () {
|
|||
await tree.updateChildren(model.root);
|
||||
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
assert(tree.getNode(model.get('a')).collapsed);
|
||||
});
|
||||
|
||||
|
@ -387,22 +386,22 @@ suite('AsyncDataTree', function () {
|
|||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
|
||||
let twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [{ id: 'aa' }];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(hasClass(twistie, 'collapsible'));
|
||||
assert(hasClass(twistie, 'collapsed'));
|
||||
assert(twistie.classList.contains('collapsible'));
|
||||
assert(twistie.classList.contains('collapsed'));
|
||||
|
||||
model.get('a').children = [];
|
||||
await tree.updateChildren(model.get('a'), false);
|
||||
assert.equal(container.querySelectorAll('.monaco-list-row').length, 1);
|
||||
twistie = container.querySelector('.monaco-list-row:first-child .monaco-tl-twistie') as HTMLElement;
|
||||
assert(!hasClass(twistie, 'collapsible'));
|
||||
assert(!hasClass(twistie, 'collapsed'));
|
||||
assert(!twistie.classList.contains('collapsible'));
|
||||
assert(!twistie.classList.contains('collapsed'));
|
||||
});
|
||||
|
||||
test('issues #84569, #82629 - rerender', async () => {
|
||||
|
|
|
@ -338,7 +338,7 @@ export class CodeWindow extends Disposable implements ICodeWindow {
|
|||
}
|
||||
|
||||
focus(options?: { force: boolean }): void {
|
||||
// macOS: Electron >6.x changed its behaviour to not
|
||||
// macOS: Electron > 7.x changed its behaviour to not
|
||||
// bring the application to the foreground when a window
|
||||
// is focused programmatically. Only via `app.focus` and
|
||||
// the option `steal: true` can you get the previous
|
||||
|
|
|
@ -207,10 +207,11 @@ export class LanguageFeatureRequestDelays {
|
|||
|
||||
get(model: ITextModel): number {
|
||||
const key = this._key(model);
|
||||
return this._clamp(this._cache.get(key)?.value);
|
||||
const avg = this._cache.get(key);
|
||||
return this._clamp(avg?.value);
|
||||
}
|
||||
|
||||
update(model: ITextModel, value: number) {
|
||||
update(model: ITextModel, value: number): number {
|
||||
const key = this._key(model);
|
||||
let avg = this._cache.get(key);
|
||||
if (!avg) {
|
||||
|
@ -218,5 +219,6 @@ export class LanguageFeatureRequestDelays {
|
|||
this._cache.set(key, avg);
|
||||
}
|
||||
avg.update(value);
|
||||
return this.get(model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IMarkerService, IMarker, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers';
|
||||
import { Disposable, toDisposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IModelDeltaDecoration, ITextModel, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, IModelDecoration, MinimapPosition, IModelDecorationMinimapOptions } from 'vs/editor/common/model';
|
||||
import { ClassName } from 'vs/editor/common/model/intervalTree';
|
||||
|
@ -16,7 +16,6 @@ import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDeco
|
|||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { minimapWarning, minimapError } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Delayer } from 'vs/base/common/async';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
|
@ -36,10 +35,6 @@ class MarkerDecorations extends Disposable {
|
|||
}));
|
||||
}
|
||||
|
||||
register<T extends IDisposable>(t: T): T {
|
||||
return super._register(t);
|
||||
}
|
||||
|
||||
public update(markers: IMarker[], newDecorations: IModelDeltaDecoration[]): boolean {
|
||||
const oldIds = [...this._markersData.keys()];
|
||||
this._markersData.clear();
|
||||
|
@ -114,8 +109,6 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
|||
private _onModelAdded(model: ITextModel): void {
|
||||
const markerDecorations = new MarkerDecorations(model);
|
||||
this._markerDecorations.set(MODEL_ID(model.uri), markerDecorations);
|
||||
const delayer = markerDecorations.register(new Delayer(100));
|
||||
markerDecorations.register(model.onDidChangeContent(() => delayer.trigger(() => this._updateDecorations(markerDecorations))));
|
||||
this._updateDecorations(markerDecorations);
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,8 @@ export class CodeLensContribution implements IEditorContribution {
|
|||
this._codeLensCache.put(model, result);
|
||||
|
||||
// update moving average
|
||||
this._getCodeLensModelDelays.update(model, Date.now() - t1);
|
||||
const newDelay = this._getCodeLensModelDelays.update(model, Date.now() - t1);
|
||||
scheduler.delay = newDelay;
|
||||
|
||||
// render lenses
|
||||
this._renderCodeLensSymbols(result);
|
||||
|
@ -331,7 +332,7 @@ export class CodeLensContribution implements IEditorContribution {
|
|||
private _resolveCodeLensesInViewportSoon(): void {
|
||||
const model = this._editor.getModel();
|
||||
if (model) {
|
||||
this._resolveCodeLensesScheduler.schedule(this._resolveCodeLensesDelays.get(model));
|
||||
this._resolveCodeLensesScheduler.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,7 +392,8 @@ export class CodeLensContribution implements IEditorContribution {
|
|||
this._resolveCodeLensesPromise.then(() => {
|
||||
|
||||
// update moving average
|
||||
this._resolveCodeLensesDelays.update(model, Date.now() - t1);
|
||||
const newDelay = this._resolveCodeLensesDelays.update(model, Date.now() - t1);
|
||||
this._resolveCodeLensesScheduler.delay = newDelay;
|
||||
|
||||
if (this._currentCodeLensModel) { // update the cached state with new resolved items
|
||||
this._codeLensCache.put(model, this._currentCodeLensModel);
|
||||
|
|
|
@ -14,7 +14,7 @@ import { editorCodeLensForeground } from 'vs/editor/common/view/editorColorRegis
|
|||
import { CodeLensItem } from 'vs/editor/contrib/codelens/codelens';
|
||||
import { editorActiveLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
class CodeLensViewZone implements IViewZone {
|
||||
|
||||
|
@ -88,7 +88,7 @@ class CodeLensContentWidget implements IContentWidget {
|
|||
}
|
||||
hasSymbol = true;
|
||||
if (lens.command) {
|
||||
const title = renderCodiconsAsElement(lens.command.title);
|
||||
const title = renderCodicons(lens.command.title);
|
||||
if (lens.command.id) {
|
||||
children.push(dom.$('a', { id: String(i) }, ...title));
|
||||
this._commands.set(String(i), lens.command);
|
||||
|
|
|
@ -47,12 +47,12 @@ export class ColorPickerHeader extends Disposable {
|
|||
this._register(model.onDidChangeColor(this.onDidChangeColor, this));
|
||||
this._register(model.onDidChangePresentation(this.onDidChangePresentation, this));
|
||||
this.pickedColorNode.style.backgroundColor = Color.Format.CSS.format(model.color) || '';
|
||||
dom.toggleClass(this.pickedColorNode, 'light', model.color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : model.color.isLighter());
|
||||
this.pickedColorNode.classList.toggle('light', model.color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : model.color.isLighter());
|
||||
}
|
||||
|
||||
private onDidChangeColor(color: Color): void {
|
||||
this.pickedColorNode.style.backgroundColor = Color.Format.CSS.format(color) || '';
|
||||
dom.toggleClass(this.pickedColorNode, 'light', color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : color.isLighter());
|
||||
this.pickedColorNode.classList.toggle('light', color.rgba.a < 0.5 ? this.backgroundColor.isLighter() : color.isLighter());
|
||||
this.onDidChangePresentation();
|
||||
}
|
||||
|
||||
|
@ -264,7 +264,7 @@ abstract class Strip extends Disposable {
|
|||
private onMouseDown(e: MouseEvent): void {
|
||||
const monitor = this._register(new GlobalMouseMoveMonitor<IStandardMouseMoveEventData>());
|
||||
const origin = dom.getDomNodePagePosition(this.domNode);
|
||||
dom.addClass(this.domNode, 'grabbing');
|
||||
this.domNode.classList.add('grabbing');
|
||||
|
||||
if (e.target !== this.slider) {
|
||||
this.onDidChangeTop(e.offsetY);
|
||||
|
@ -276,7 +276,7 @@ abstract class Strip extends Disposable {
|
|||
this._onColorFlushed.fire();
|
||||
mouseUpListener.dispose();
|
||||
monitor.stopMonitoring(true);
|
||||
dom.removeClass(this.domNode, 'grabbing');
|
||||
this.domNode.classList.remove('grabbing');
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
@ -298,7 +298,7 @@ class OpacityStrip extends Strip {
|
|||
|
||||
constructor(container: HTMLElement, model: ColorPickerModel) {
|
||||
super(container, model);
|
||||
dom.addClass(this.domNode, 'opacity-strip');
|
||||
this.domNode.classList.add('opacity-strip');
|
||||
|
||||
this._register(model.onDidChangeColor(this.onDidChangeColor, this));
|
||||
this.onDidChangeColor(this.model.color);
|
||||
|
@ -321,7 +321,7 @@ class HueStrip extends Strip {
|
|||
|
||||
constructor(container: HTMLElement, model: ColorPickerModel) {
|
||||
super(container, model);
|
||||
dom.addClass(this.domNode, 'hue-strip');
|
||||
this.domNode.classList.add('hue-strip');
|
||||
}
|
||||
|
||||
protected getValue(color: Color): number {
|
||||
|
|
|
@ -116,7 +116,7 @@ export abstract class FormattingConflicts {
|
|||
if (selector) {
|
||||
return await selector(formatter, document, mode);
|
||||
}
|
||||
return formatter[0];
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ export class CompletionModel {
|
|||
private _refilterKind: Refilter;
|
||||
private _filteredItems?: StrictCompletionItem[];
|
||||
private _isIncomplete?: Set<CompletionItemProvider>;
|
||||
private _allProvider?: Set<CompletionItemProvider>; // TODO@jrieken merge incomplete and all provider info
|
||||
private _stats?: ICompletionStats;
|
||||
|
||||
constructor(
|
||||
|
@ -99,6 +100,11 @@ export class CompletionModel {
|
|||
return this._filteredItems!;
|
||||
}
|
||||
|
||||
get allProvider(): Set<CompletionItemProvider> {
|
||||
this._ensureCachedState();
|
||||
return this._allProvider!;
|
||||
}
|
||||
|
||||
get incomplete(): Set<CompletionItemProvider> {
|
||||
this._ensureCachedState();
|
||||
return this._isIncomplete!;
|
||||
|
@ -136,6 +142,7 @@ export class CompletionModel {
|
|||
private _createCachedState(): void {
|
||||
|
||||
this._isIncomplete = new Set();
|
||||
this._allProvider = new Set();
|
||||
this._stats = { suggestionCount: 0, snippetCount: 0, textCount: 0 };
|
||||
|
||||
const { leadingLineContent, characterCountDelta } = this._lineContext;
|
||||
|
@ -164,6 +171,7 @@ export class CompletionModel {
|
|||
if (item.container.incomplete) {
|
||||
this._isIncomplete.add(item.provider);
|
||||
}
|
||||
this._allProvider.add(item.provider);
|
||||
|
||||
// 'word' is that remainder of the current line that we
|
||||
// filter and score against. In theory each suggestion uses a
|
||||
|
|
|
@ -44,6 +44,7 @@ export interface ISuggestEvent {
|
|||
export interface SuggestTriggerContext {
|
||||
readonly auto: boolean;
|
||||
readonly shy: boolean;
|
||||
readonly triggerKind?: CompletionTriggerKind;
|
||||
readonly triggerCharacter?: string;
|
||||
}
|
||||
|
||||
|
@ -393,16 +394,12 @@ export class SuggestModel implements IDisposable {
|
|||
this._context = ctx;
|
||||
|
||||
// Build context for request
|
||||
let suggestCtx: CompletionContext;
|
||||
let suggestCtx: CompletionContext = { triggerKind: context.triggerKind ?? CompletionTriggerKind.Invoke };
|
||||
if (context.triggerCharacter) {
|
||||
suggestCtx = {
|
||||
triggerKind: CompletionTriggerKind.TriggerCharacter,
|
||||
triggerCharacter: context.triggerCharacter
|
||||
};
|
||||
} else if (onlyFrom && onlyFrom.size > 0) {
|
||||
suggestCtx = { triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions };
|
||||
} else {
|
||||
suggestCtx = { triggerKind: CompletionTriggerKind.Invoke };
|
||||
}
|
||||
|
||||
this._requestToken = new CancellationTokenSource();
|
||||
|
@ -558,7 +555,13 @@ export class SuggestModel implements IDisposable {
|
|||
|
||||
if (ctx.leadingWord.word.length !== 0 && ctx.leadingWord.startColumn > this._context.leadingWord.startColumn) {
|
||||
// started a new word while IntelliSense shows -> retrigger
|
||||
this.trigger({ auto: this._context.auto, shy: false }, true);
|
||||
|
||||
// Select those providers have not contributed to this completion model and re-trigger completions for
|
||||
// them. Also adopt the existing items and merge them into the new completion model
|
||||
const inactiveProvider = new Set(CompletionProviderRegistry.all(this._editor.getModel()!));
|
||||
this._completionModel.allProvider.forEach(provider => inactiveProvider.delete(provider));
|
||||
const items = this._completionModel.adopt(new Set());
|
||||
this.trigger({ auto: this._context.auto, shy: false }, true, inactiveProvider, items);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -566,7 +569,7 @@ export class SuggestModel implements IDisposable {
|
|||
// typed -> moved cursor RIGHT & incomple model & still on a word -> retrigger
|
||||
const { incomplete } = this._completionModel;
|
||||
const adopted = this._completionModel.adopt(incomplete);
|
||||
this.trigger({ auto: this._state === State.Auto, shy: false }, true, incomplete, adopted);
|
||||
this.trigger({ auto: this._state === State.Auto, shy: false, triggerKind: CompletionTriggerKind.TriggerForIncompleteCompletions }, true, incomplete, adopted);
|
||||
|
||||
} else {
|
||||
// typed -> moved cursor RIGHT -> update UI
|
||||
|
|
|
@ -815,6 +815,9 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
|||
disposables.push(CompletionProviderRegistry.register({ scheme: 'test' }, {
|
||||
provideCompletionItems(doc, pos) {
|
||||
countB += 1;
|
||||
if (!doc.getWordUntilPosition(pos).word.startsWith('a')) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
incomplete: false,
|
||||
suggestions: [{
|
||||
|
@ -850,7 +853,7 @@ suite('SuggestModel - TriggerAndCancelOracle', function () {
|
|||
assert.equal(event.completionModel.items[0].textLabel, 'Z aaa');
|
||||
assert.equal(event.completionModel.items[1].textLabel, 'aaa');
|
||||
|
||||
assert.equal(countA, 2); // should we keep the suggestions from the "active" provider?
|
||||
assert.equal(countA, 1); // should we keep the suggestions from the "active" provider?, Yes! See: #106573
|
||||
assert.equal(countB, 2);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -95,6 +95,7 @@ export interface INativeEnvironmentService extends IEnvironmentService {
|
|||
appRoot: string;
|
||||
userHome: URI;
|
||||
appSettingsHome: URI;
|
||||
tmpDir: URI;
|
||||
userDataPath: string;
|
||||
machineSettingsResource: URI;
|
||||
backupHome: string;
|
||||
|
|
|
@ -44,6 +44,9 @@ export class EnvironmentService implements INativeEnvironmentService {
|
|||
@memoize
|
||||
get appSettingsHome(): URI { return URI.file(path.join(this.userDataPath, 'User')); }
|
||||
|
||||
@memoize
|
||||
get tmpDir(): URI { return URI.file(os.tmpdir()); }
|
||||
|
||||
@memoize
|
||||
get userRoamingDataHome(): URI { return this.appSettingsHome; }
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ import { ExtensionsManifestCache } from 'vs/platform/extensionManagement/node/ex
|
|||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { isEngineValid } from 'vs/platform/extensions/common/extensionValidator';
|
||||
import { tmpdir } from 'os';
|
||||
import { joinPath } from 'vs/base/common/resources';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { IDownloadService } from 'vs/platform/download/common/download';
|
||||
import { optional, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
@ -83,7 +83,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
onDidUninstallExtension: Event<DidUninstallExtensionEvent> = this._onDidUninstallExtension.event;
|
||||
|
||||
constructor(
|
||||
@IEnvironmentService environmentService: INativeEnvironmentService,
|
||||
@IEnvironmentService private readonly environmentService: INativeEnvironmentService,
|
||||
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@optional(IDownloadService) private downloadService: IDownloadService,
|
||||
|
@ -107,7 +107,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
async zip(extension: ILocalExtension): Promise<URI> {
|
||||
this.logService.trace('ExtensionManagementService#zip', extension.identifier.id);
|
||||
const files = await this.collectFiles(extension);
|
||||
const location = await zip(path.join(tmpdir(), generateUuid()), files);
|
||||
const location = await zip(joinPath(this.environmentService.tmpDir, generateUuid()).fsPath, files);
|
||||
return URI.file(location);
|
||||
}
|
||||
|
||||
|
@ -217,7 +217,7 @@ export class ExtensionManagementService extends Disposable implements IExtension
|
|||
throw new Error('Download service is not available');
|
||||
}
|
||||
|
||||
const downloadedLocation = URI.file(path.join(tmpdir(), generateUuid()));
|
||||
const downloadedLocation = joinPath(this.environmentService.tmpDir, generateUuid());
|
||||
await this.downloadService.download(vsix, downloadedLocation);
|
||||
return downloadedLocation;
|
||||
}
|
||||
|
|
|
@ -73,10 +73,18 @@ export class LaunchMainService implements ILaunchMainService {
|
|||
async start(args: NativeParsedArgs, userEnv: IProcessEnvironment): Promise<void> {
|
||||
this.logService.trace('Received data from other instance: ', args, userEnv);
|
||||
|
||||
// Since we now start to open a window, make sure the app has focus.
|
||||
// Focussing a window will not ensure that the application itself
|
||||
// has focus, so we use the `steal: true` hint to force focus.
|
||||
app.focus({ steal: true });
|
||||
// macOS: Electron > 7.x changed its behaviour to not
|
||||
// bring the application to the foreground when a window
|
||||
// is focused programmatically. Only via `app.focus` and
|
||||
// the option `steal: true` can you get the previous
|
||||
// behaviour back. The only reason to use this option is
|
||||
// when a window is getting focused while the application
|
||||
// is not in the foreground and since we got instructed
|
||||
// to open a new window from another instance, we ensure
|
||||
// that the app has focus.
|
||||
if (isMacintosh) {
|
||||
app.focus({ steal: true });
|
||||
}
|
||||
|
||||
// Check early for open-url which is handled in URL service
|
||||
const urlsToOpen = parseOpenUrl(args);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
import { readdirSync } from 'vs/base/node/pfs';
|
||||
import { statSync, readFileSync } from 'fs';
|
||||
import { join } from 'vs/base/common/path';
|
||||
|
@ -43,4 +42,4 @@ export function buildTelemetryMessage(appRoot: string, extensionsPath?: string):
|
|||
contents = readFileSync(join(appRoot, 'telemetry-extensions.json')).toString();
|
||||
mergeTelemetry(contents, 'vscode-extensions');
|
||||
return JSON.stringify(mergedTelemetry, null, 4);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { Event } from 'vs/base/common/event';
|
||||
import { IURLHandler, IOpenURLOptions } from 'vs/platform/url/common/url';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { first } from 'vs/base/common/arrays';
|
||||
|
||||
export class URLHandlerChannel implements IServerChannel {
|
||||
|
||||
|
@ -54,7 +53,7 @@ export class URLHandlerRouter implements IClientRouter<string> {
|
|||
if (match) {
|
||||
const windowId = match[1];
|
||||
const regex = new RegExp(`window:${windowId}`);
|
||||
const connection = first(hub.connections, c => regex.test(c.ctx));
|
||||
const connection = hub.connections.find(c => regex.test(c.ctx));
|
||||
|
||||
if (connection) {
|
||||
return connection;
|
||||
|
|
|
@ -138,6 +138,8 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
|
|||
async stop(): Promise<void> {
|
||||
if (cancellablePromise) {
|
||||
cancellablePromise.cancel();
|
||||
}
|
||||
if (that.status !== SyncStatus.Idle) {
|
||||
return that.stop();
|
||||
}
|
||||
}
|
||||
|
|
22
src/vs/vscode.d.ts
vendored
22
src/vs/vscode.d.ts
vendored
|
@ -4700,7 +4700,7 @@ declare module 'vscode' {
|
|||
* The *effective* value (returned by [`get`](#WorkspaceConfiguration.get)) is computed by overriding or merging the values in the following order.
|
||||
*
|
||||
* ```
|
||||
* `defaultValue`
|
||||
* `defaultValue` (if defined in `package.json` otherwise derived from the value's type)
|
||||
* `globalValue` (if defined)
|
||||
* `workspaceValue` (if defined)
|
||||
* `workspaceFolderValue` (if defined)
|
||||
|
@ -10598,6 +10598,26 @@ declare module 'vscode' {
|
|||
* resource state.
|
||||
*/
|
||||
readonly decorations?: SourceControlResourceDecorations;
|
||||
|
||||
/**
|
||||
* Context value of the resource state. This can be used to contribute resource specific actions.
|
||||
* For example, if a resource is given a context value as `diffable`. When contributing actions to `scm/resourceState/context`
|
||||
* using `menus` extension point, you can specify context value for key `scmResourceState` in `when` expressions, like `scmResourceState == diffable`.
|
||||
* ```
|
||||
* "contributes": {
|
||||
* "menus": {
|
||||
* "scm/resourceState/context": [
|
||||
* {
|
||||
* "command": "extension.diff",
|
||||
* "when": "scmResourceState == diffable"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* This will show action `extension.diff` only for resources with `contextValue` is `diffable`.
|
||||
*/
|
||||
readonly contextValue?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
56
src/vs/vscode.proposed.d.ts
vendored
56
src/vs/vscode.proposed.d.ts
vendored
|
@ -1313,6 +1313,7 @@ declare module 'vscode' {
|
|||
}
|
||||
|
||||
export interface NotebookCell {
|
||||
readonly index: number;
|
||||
readonly notebook: NotebookDocument;
|
||||
readonly uri: Uri;
|
||||
readonly cellKind: CellKind;
|
||||
|
@ -1399,27 +1400,16 @@ declare module 'vscode' {
|
|||
|
||||
export interface WorkspaceEdit {
|
||||
replaceNotebookMetadata(uri: Uri, value: NotebookDocumentMetadata): void;
|
||||
replaceCells(uri: Uri, start: number, end: number, cells: NotebookCellData[], metadata?: WorkspaceEditEntryMetadata): void;
|
||||
replaceCellOutput(uri: Uri, index: number, outputs: CellOutput[], metadata?: WorkspaceEditEntryMetadata): void;
|
||||
replaceCellMetadata(uri: Uri, index: number, cellMetadata: NotebookCellMetadata, metadata?: WorkspaceEditEntryMetadata): void;
|
||||
replaceNotebookCells(uri: Uri, start: number, end: number, cells: NotebookCellData[], metadata?: WorkspaceEditEntryMetadata): void;
|
||||
replaceNotebookCellOutput(uri: Uri, index: number, outputs: CellOutput[], metadata?: WorkspaceEditEntryMetadata): void;
|
||||
replaceNotebookCellMetadata(uri: Uri, index: number, cellMetadata: NotebookCellMetadata, metadata?: WorkspaceEditEntryMetadata): void;
|
||||
}
|
||||
|
||||
export interface NotebookEditorEdit {
|
||||
|
||||
replaceNotebookMetadata(value: NotebookDocumentMetadata): void;
|
||||
|
||||
replaceMetadata(value: NotebookDocumentMetadata): void;
|
||||
replaceCells(start: number, end: number, cells: NotebookCellData[]): void;
|
||||
replaceCellOutput(index: number, outputs: CellOutput[]): void;
|
||||
replaceCellMetadata(index: number, metadata: NotebookCellMetadata): void;
|
||||
|
||||
/** @deprecated */
|
||||
replaceOutput(index: number, outputs: CellOutput[]): void;
|
||||
/** @deprecated */
|
||||
replaceMetadata(index: number, metadata: NotebookCellMetadata): void;
|
||||
/** @deprecated */
|
||||
insert(index: number, content: string | string[], language: string, type: CellKind, outputs: CellOutput[], metadata: NotebookCellMetadata | undefined): void;
|
||||
/** @deprecated */
|
||||
delete(index: number): void;
|
||||
}
|
||||
|
||||
export interface NotebookCellRange {
|
||||
|
@ -1503,6 +1493,16 @@ declare module 'vscode' {
|
|||
*/
|
||||
asWebviewUri(localResource: Uri): Uri;
|
||||
|
||||
/**
|
||||
* Perform an edit on the notebook associated with this notebook editor.
|
||||
*
|
||||
* The given callback-function is invoked with an [edit-builder](#NotebookEditorEdit) which must
|
||||
* be used to make edits. Note that the edit-builder is only valid while the
|
||||
* callback executes.
|
||||
*
|
||||
* @param callback A function which can create edits using an [edit-builder](#NotebookEditorEdit).
|
||||
* @return A promise that resolves with a value indicating if the edits could be applied.
|
||||
*/
|
||||
edit(callback: (editBuilder: NotebookEditorEdit) => void): Thenable<boolean>;
|
||||
|
||||
revealRange(range: NotebookCellRange, revealType?: NotebookEditorRevealType): void;
|
||||
|
@ -2040,32 +2040,6 @@ declare module 'vscode' {
|
|||
|
||||
//#endregion
|
||||
|
||||
//#region Support `scmResourceState` in `when` clauses #86180 https://github.com/microsoft/vscode/issues/86180
|
||||
|
||||
export interface SourceControlResourceState {
|
||||
/**
|
||||
* Context value of the resource state. This can be used to contribute resource specific actions.
|
||||
* For example, if a resource is given a context value as `diffable`. When contributing actions to `scm/resourceState/context`
|
||||
* using `menus` extension point, you can specify context value for key `scmResourceState` in `when` expressions, like `scmResourceState == diffable`.
|
||||
* ```
|
||||
* "contributes": {
|
||||
* "menus": {
|
||||
* "scm/resourceState/context": [
|
||||
* {
|
||||
* "command": "extension.diff",
|
||||
* "when": "scmResourceState == diffable"
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
* This will show action `extension.diff` only for resources with `contextValue` is `diffable`.
|
||||
*/
|
||||
readonly contextValue?: string;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region https://github.com/microsoft/vscode/issues/104436
|
||||
|
||||
export enum ExtensionRuntime {
|
||||
|
|
|
@ -29,8 +29,8 @@ import { CustomDocumentBackupData } from 'vs/workbench/contrib/customEditor/brow
|
|||
import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
|
||||
import { CustomTextEditorModel } from 'vs/workbench/contrib/customEditor/common/customTextEditorModel';
|
||||
import { WebviewExtensionDescription } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
||||
import { IWebviewWorkbenchService } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
|
||||
import { IWebviewWorkbenchService } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
|
|
@ -162,7 +162,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
return false;
|
||||
}
|
||||
this._notebookService.transformEditsOutputs(textModel, cellEdits);
|
||||
return textModel.applyEdit(modelVersionId, cellEdits, true, undefined, () => undefined);
|
||||
return textModel.applyEdits(modelVersionId, cellEdits, true, undefined, () => undefined);
|
||||
}
|
||||
|
||||
private _isDeltaEmpty(delta: INotebookDocumentsAndEditorsDelta) {
|
||||
|
@ -460,7 +460,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
this._notebookService.transformEditsOutputs(mainthreadTextModel, edits);
|
||||
await new Promise(resolve => {
|
||||
DOM.scheduleAtNextAnimationFrame(() => {
|
||||
const ret = mainthreadTextModel!.applyEdit(mainthreadTextModel!.versionId, edits, true, undefined, () => undefined);
|
||||
const ret = mainthreadTextModel!.applyEdits(mainthreadTextModel!.versionId, edits, true, undefined, () => undefined);
|
||||
resolve(ret);
|
||||
});
|
||||
});
|
||||
|
@ -577,7 +577,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
return;
|
||||
}
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{
|
||||
editType: CellEditType.OutputsSplice,
|
||||
index: textModel.cells.indexOf(cell),
|
||||
|
@ -614,7 +614,7 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
const textModel = this._notebookService.getNotebookTextModel(URI.from(resource));
|
||||
|
||||
if (textModel) {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{
|
||||
editType: CellEditType.Unknown
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation } from 'vs/workbench/contrib/scm/common/scm';
|
||||
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, IExtHostContext } from '../common/extHost.protocol';
|
||||
|
@ -49,7 +48,7 @@ class MainThreadSCMResourceGroup implements ISCMResourceGroup {
|
|||
}
|
||||
|
||||
$updateGroup(features: SCMGroupFeatures): void {
|
||||
this.features = assign(this.features, features);
|
||||
this.features = { ...this.features, ...features };
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
|
||||
|
@ -139,7 +138,7 @@ class MainThreadSCMProvider implements ISCMProvider {
|
|||
) { }
|
||||
|
||||
$updateSourceControl(features: SCMProviderFeatures): void {
|
||||
this.features = assign(this.features, features);
|
||||
this.features = { ...this.features, ...features };
|
||||
this._onDidChange.fire();
|
||||
|
||||
if (typeof features.commitTemplate !== 'undefined') {
|
||||
|
|
|
@ -13,8 +13,8 @@ import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } fr
|
|||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
||||
import { WebviewIcons } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
|
||||
import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { WebviewInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInput';
|
||||
import { ICreateWebViewShowOptions, IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
|
|
@ -15,7 +15,7 @@ import { IOpenerService } from 'vs/platform/opener/common/opener';
|
|||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import * as extHostProtocol from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Webview, WebviewExtensionDescription, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { WebviewInputOptions } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
|
||||
export class MainThreadWebviews extends Disposable implements extHostProtocol.MainThreadWebviewsShape {
|
||||
|
||||
|
|
|
@ -1032,7 +1032,7 @@ export class ExtHostVariableResolverService extends AbstractVariableResolverServ
|
|||
}
|
||||
return undefined;
|
||||
}
|
||||
}, env, !editorService);
|
||||
}, undefined, env, !editorService);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
|||
let lastUri: vscode.Uri | undefined;
|
||||
|
||||
// ensure stable-sort
|
||||
mergeSort(first, DiagnosticCollection._compareIndexedTuplesByUri);
|
||||
first = mergeSort([...first], DiagnosticCollection._compareIndexedTuplesByUri);
|
||||
|
||||
for (const tuple of first) {
|
||||
const [uri, diagnostics] = tuple;
|
||||
|
@ -88,17 +88,17 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
|||
}
|
||||
lastUri = uri;
|
||||
toSync.push(uri);
|
||||
this._data.set(uri.toString(), []);
|
||||
this._data.set(uri, []);
|
||||
}
|
||||
|
||||
if (!diagnostics) {
|
||||
// [Uri, undefined] means clear this
|
||||
const currentDiagnostics = this._data.get(uri.toString());
|
||||
const currentDiagnostics = this._data.get(uri);
|
||||
if (currentDiagnostics) {
|
||||
currentDiagnostics.length = 0;
|
||||
}
|
||||
} else {
|
||||
const currentDiagnostics = this._data.get(uri.toString());
|
||||
const currentDiagnostics = this._data.get(uri);
|
||||
if (currentDiagnostics) {
|
||||
currentDiagnostics.push(...diagnostics);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export class DiagnosticCollection implements vscode.DiagnosticCollection {
|
|||
}
|
||||
}
|
||||
|
||||
private static _compareIndexedTuplesByUri(a: [vscode.Uri, vscode.Diagnostic[]], b: [vscode.Uri, vscode.Diagnostic[]]): number {
|
||||
private static _compareIndexedTuplesByUri(a: [vscode.Uri, readonly vscode.Diagnostic[]], b: [vscode.Uri, readonly vscode.Diagnostic[]]): number {
|
||||
if (a[0].toString() < b[0].toString()) {
|
||||
return -1;
|
||||
} else if (a[0].toString() > b[0].toString()) {
|
||||
|
|
|
@ -115,6 +115,7 @@ export class ExtHostCell extends Disposable {
|
|||
const that = this;
|
||||
const document = this._extHostDocument.getDocument(this.uri)!.document;
|
||||
this._cell = Object.freeze({
|
||||
get index() { return that._notebook.getCellIndex(that); },
|
||||
notebook: that._notebook.notebookDocument,
|
||||
uri: that.uri,
|
||||
cellKind: this._cellData.cellKind,
|
||||
|
@ -487,6 +488,9 @@ export class ExtHostNotebookDocument extends Disposable {
|
|||
return this._cells.find(cell => cell.handle === cellHandle);
|
||||
}
|
||||
|
||||
getCellIndex(cell: ExtHostCell): number {
|
||||
return this._cells.indexOf(cell);
|
||||
}
|
||||
|
||||
addEdit(item: vscode.NotebookDocumentEditEvent): number {
|
||||
return this._edits.add([item]);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import { readonly } from 'vs/base/common/errors';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { CellKind, MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { MainThreadNotebookShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import * as extHostTypes from 'vs/workbench/api/common/extHostTypes';
|
||||
import { addIdToOutput, CellEditType, ICellEditOperation, ICellReplaceEdit, INotebookEditData, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import * as vscode from 'vscode';
|
||||
|
@ -37,7 +37,7 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
|
|||
}
|
||||
}
|
||||
|
||||
replaceNotebookMetadata(value: vscode.NotebookDocumentMetadata): void {
|
||||
replaceMetadata(value: vscode.NotebookDocumentMetadata): void {
|
||||
this._throwIfFinalized();
|
||||
this._collectedEdits.push({
|
||||
editType: CellEditType.DocumentMetadata,
|
||||
|
@ -54,12 +54,6 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
|
|||
});
|
||||
}
|
||||
|
||||
replaceMetadata(index: number, metadata: vscode.NotebookCellMetadata): void {
|
||||
console.warn('DEPRECATED use "replaceCellMetadata" instead');
|
||||
this.replaceCellMetadata(index, metadata);
|
||||
}
|
||||
|
||||
|
||||
replaceCellOutput(index: number, outputs: vscode.CellOutput[]): void {
|
||||
this._throwIfFinalized();
|
||||
this._collectedEdits.push({
|
||||
|
@ -69,14 +63,11 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
|
|||
});
|
||||
}
|
||||
|
||||
replaceOutput(index: number, outputs: vscode.CellOutput[]): void {
|
||||
console.warn('DEPRECATED use "replaceCellOutput" instead');
|
||||
this.replaceCellOutput(index, outputs);
|
||||
}
|
||||
|
||||
replaceCells(from: number, to: number, cells: vscode.NotebookCellData[]): void {
|
||||
this._throwIfFinalized();
|
||||
|
||||
if (from === to && cells.length === 0) {
|
||||
return;
|
||||
}
|
||||
this._collectedEdits.push({
|
||||
editType: CellEditType.Replace,
|
||||
index: from,
|
||||
|
@ -89,22 +80,6 @@ class NotebookEditorCellEditBuilder implements vscode.NotebookEditorEdit {
|
|||
})
|
||||
});
|
||||
}
|
||||
|
||||
insert(index: number, content: string | string[], language: string, type: CellKind, outputs: vscode.CellOutput[], metadata: vscode.NotebookCellMetadata | undefined): void {
|
||||
this._throwIfFinalized();
|
||||
this.replaceCells(index, index, [{
|
||||
language,
|
||||
outputs,
|
||||
metadata,
|
||||
cellKind: type,
|
||||
source: Array.isArray(content) ? content.join('\n') : content,
|
||||
}]);
|
||||
}
|
||||
|
||||
delete(index: number): void {
|
||||
this._throwIfFinalized();
|
||||
this.replaceCells(index, 1, []);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostNotebookEditor extends Disposable implements vscode.NotebookEditor {
|
||||
|
|
|
@ -636,15 +636,17 @@ export class WorkspaceEdit implements vscode.WorkspaceEdit {
|
|||
this._edits.push({ _type: FileEditType.Cell, metadata, uri, notebookMetadata: value });
|
||||
}
|
||||
|
||||
replaceCells(uri: URI, start: number, end: number, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Replace, index: start, count: end - start, cells: cells.map(cell => ({ ...cell, outputs: cell.outputs.map(output => addIdToOutput(output)) })) } });
|
||||
replaceNotebookCells(uri: URI, start: number, end: number, cells: vscode.NotebookCellData[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
if (start !== end || cells.length > 0) {
|
||||
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Replace, index: start, count: end - start, cells: cells.map(cell => ({ ...cell, outputs: cell.outputs.map(output => addIdToOutput(output)) })) } });
|
||||
}
|
||||
}
|
||||
|
||||
replaceCellOutput(uri: URI, index: number, outputs: vscode.CellOutput[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
replaceNotebookCellOutput(uri: URI, index: number, outputs: vscode.CellOutput[], metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Output, index, outputs: outputs.map(output => addIdToOutput(output)) } });
|
||||
}
|
||||
|
||||
replaceCellMetadata(uri: URI, index: number, cellMetadata: vscode.NotebookCellMetadata, metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
replaceNotebookCellMetadata(uri: URI, index: number, cellMetadata: vscode.NotebookCellMetadata, metadata?: vscode.WorkspaceEditEntryMetadata): void {
|
||||
this._edits.push({ _type: FileEditType.Cell, metadata, uri, edit: { editType: CellEditType.Metadata, index, metadata: cellMetadata } });
|
||||
}
|
||||
|
||||
|
|
|
@ -368,7 +368,7 @@ namespace schema {
|
|||
};
|
||||
|
||||
export const submenusContribution: IJSONSchema = {
|
||||
description: localize('vscode.extension.contributes.submenus', "(Proposed API) Contributes submenu items to the editor"),
|
||||
description: localize('vscode.extension.contributes.submenus', "Contributes submenu items to the editor"),
|
||||
type: 'array',
|
||||
items: submenu
|
||||
};
|
||||
|
@ -585,11 +585,6 @@ submenusExtensionPoint.setHandler(extensions => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!extension.description.enableProposedApi) {
|
||||
collector.error(localize('submenu.proposedAPI.invalid', "Submenus are proposed API and are only available when running out of dev or with the following command line switch: --enable-proposed-api {0}", extension.description.identifier.value));
|
||||
return;
|
||||
}
|
||||
|
||||
let absoluteIcon: { dark: URI; light?: URI; } | ThemeIcon | undefined;
|
||||
if (entry.value.icon) {
|
||||
if (typeof entry.value.icon === 'string') {
|
||||
|
@ -638,7 +633,6 @@ menusExtensionPoint.setHandler(extensions => {
|
|||
}
|
||||
|
||||
let menu = _apiMenusByKey.get(entry.key);
|
||||
let isSubmenu = false;
|
||||
|
||||
if (!menu) {
|
||||
const submenu = _submenus.get(entry.key);
|
||||
|
@ -649,7 +643,6 @@ menusExtensionPoint.setHandler(extensions => {
|
|||
id: submenu.id,
|
||||
description: ''
|
||||
};
|
||||
isSubmenu = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -663,11 +656,6 @@ menusExtensionPoint.setHandler(extensions => {
|
|||
return;
|
||||
}
|
||||
|
||||
if (isSubmenu && !extension.description.enableProposedApi) {
|
||||
collector.error(localize('proposedAPI.invalid.submenu', "{0} is a submenu identifier and is only available when running out of dev or with the following command line switch: --enable-proposed-api {1}", entry.key, extension.description.identifier.value));
|
||||
return;
|
||||
}
|
||||
|
||||
for (const menuItem of entry.value) {
|
||||
let item: IMenuItem | ISubmenuItem;
|
||||
|
||||
|
@ -688,13 +676,8 @@ menusExtensionPoint.setHandler(extensions => {
|
|||
|
||||
item = { command, alt, group: undefined, order: undefined, when: undefined };
|
||||
} else {
|
||||
if (!extension.description.enableProposedApi) {
|
||||
collector.error(localize('proposedAPI.invalid.submenureference', "Menu item references a submenu which is only available when running out of dev or with the following command line switch: --enable-proposed-api {0}", extension.description.identifier.value));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (menu.supportsSubmenus === false) {
|
||||
collector.error(localize('proposedAPI.unsupported.submenureference', "Menu item references a submenu for a menu which doesn't have submenu support."));
|
||||
collector.error(localize('unsupported.submenureference', "Menu item references a submenu for a menu which doesn't have submenu support."));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { IsFullscreenContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IsMacNativeContext, IsDevelopmentContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { IsMacNativeContext, IsDevelopmentContext, IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IQuickInputButton, IQuickInputService, IQuickPickSeparator, IKeyMods, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
|
@ -345,7 +345,7 @@ const viewCategory = nls.localize('view', "View");
|
|||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleFullScreenAction, { primary: KeyCode.F11, mac: { primary: KeyMod.CtrlCmd | KeyMod.WinCtrl | KeyCode.KEY_F } }), 'View: Toggle Full Screen', viewCategory);
|
||||
|
||||
const developerCategory = nls.localize({ key: 'developer', comment: ['A developer on Code itself or someone diagnosing issues in Code'] }, "Developer");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReloadWindowAction), 'Developer: Reload Window', developerCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ReloadWindowAction), 'Developer: Reload Window', developerCategory, IsWebContext.toNegated());
|
||||
|
||||
const helpCategory = nls.localize('help', "Help");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowAboutDialogAction), `Help: About`, helpCategory);
|
||||
|
|
|
@ -13,7 +13,7 @@ import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/c
|
|||
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL, PICK_WORKSPACE_FOLDER_COMMAND_ID } from 'vs/workbench/browser/actions/workspaceCommands';
|
||||
import { IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { MenuRegistry, MenuId, SyncActionDescriptor } from 'vs/platform/actions/common/actions';
|
||||
import { WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { EmptyWorkspaceSupportContext, WorkbenchStateContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
|
@ -257,7 +257,7 @@ const workspacesCategory = nls.localize('workspaces', "Workspaces");
|
|||
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(AddRootFolderAction), 'Workspaces: Add Folder to Workspace...', workspacesCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(GlobalRemoveRootFolderAction), 'Workspaces: Remove Folder from Workspace...', workspacesCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseWorkspaceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(CloseWorkspaceAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_F) }), 'Workspaces: Close Workspace', workspacesCategory, EmptyWorkspaceSupportContext);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(SaveWorkspaceAsAction), 'Workspaces: Save Workspace As...', workspacesCategory);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(DuplicateWorkspaceInNewWindowAction), 'Workspaces: Duplicate Workspace in New Window', workspacesCategory);
|
||||
|
||||
|
@ -301,7 +301,7 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
|||
precondition: WorkspaceFolderCountContext.notEqualsTo('0')
|
||||
},
|
||||
order: 3,
|
||||
when: WorkbenchStateContext.notEqualsTo('workspace')
|
||||
when: ContextKeyExpr.and(WorkbenchStateContext.notEqualsTo('workspace'), EmptyWorkspaceSupportContext)
|
||||
});
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
||||
|
@ -311,5 +311,5 @@ MenuRegistry.appendMenuItem(MenuId.MenubarFileMenu, {
|
|||
title: nls.localize({ key: 'miCloseWorkspace', comment: ['&& denotes a mnemonic'] }, "Close &&Workspace")
|
||||
},
|
||||
order: 3,
|
||||
when: ContextKeyExpr.and(WorkbenchStateContext.isEqualTo('workspace'))
|
||||
when: ContextKeyExpr.and(WorkbenchStateContext.isEqualTo('workspace'), EmptyWorkspaceSupportContext)
|
||||
});
|
||||
|
|
|
@ -20,9 +20,11 @@ import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
|
|||
import { PanelPositionContext } from 'vs/workbench/common/panel';
|
||||
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
|
||||
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { isNative } from 'vs/base/common/platform';
|
||||
|
||||
export const WorkbenchStateContext = new RawContextKey<string>('workbenchState', undefined);
|
||||
export const WorkspaceFolderCountContext = new RawContextKey<number>('workspaceFolderCount', 0);
|
||||
export const EmptyWorkspaceSupportContext = new RawContextKey<boolean>('emptyWorkspaceSupport', true);
|
||||
|
||||
export const DirtyWorkingCopiesContext = new RawContextKey<boolean>('dirtyWorkingCopies', false);
|
||||
|
||||
|
@ -51,6 +53,7 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
|||
|
||||
private workbenchStateContext: IContextKey<string>;
|
||||
private workspaceFolderCountContext: IContextKey<number>;
|
||||
private emptyWorkspaceSupportContext: IContextKey<boolean>;
|
||||
|
||||
private inZenModeContext: IContextKey<boolean>;
|
||||
private isFullscreenContext: IContextKey<boolean>;
|
||||
|
@ -112,6 +115,12 @@ export class WorkbenchContextKeysHandler extends Disposable {
|
|||
this.workspaceFolderCountContext = WorkspaceFolderCountContext.bindTo(this.contextKeyService);
|
||||
this.updateWorkspaceFolderCountContextKey();
|
||||
|
||||
// Empty workspace support: empty workspaces require a default "local" file
|
||||
// system to operate with. We always have one when running natively or when
|
||||
// we have a remote connection.
|
||||
this.emptyWorkspaceSupportContext = EmptyWorkspaceSupportContext.bindTo(this.contextKeyService);
|
||||
this.emptyWorkspaceSupportContext.set(isNative || typeof this.environmentService.configuration.remoteAuthority === 'string');
|
||||
|
||||
// Editor Layout
|
||||
this.splitEditorsVerticallyContext = SplitEditorsVertically.bindTo(this.contextKeyService);
|
||||
this.updateSplitEditorsVerticallyContext();
|
||||
|
|
|
@ -13,7 +13,7 @@ import { IBadge, NumberBadge } from 'vs/workbench/services/activity/common/activ
|
|||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDisposable, toDisposable, DisposableStore, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ToggleActivityBarVisibilityAction, ToggleMenuBarAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { ToggleActivityBarVisibilityAction, ToggleMenuBarAction, ToggleSidebarPositionAction } from 'vs/workbench/browser/actions/layoutActions';
|
||||
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
|
||||
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_ACTIVE_BORDER, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND, ACTIVITY_BAR_ACTIVE_BACKGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BORDER } from 'vs/workbench/common/theme';
|
||||
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
@ -179,6 +179,7 @@ export class ActivitybarPart extends Part implements IActivityBarService {
|
|||
actions.push(toggleAccountsVisibilityAction);
|
||||
actions.push(new Separator());
|
||||
|
||||
actions.push(this.instantiationService.createInstance(ToggleSidebarPositionAction, ToggleSidebarPositionAction.ID, ToggleSidebarPositionAction.getLabel(this.layoutService)));
|
||||
actions.push(new Action(
|
||||
ToggleActivityBarVisibilityAction.ID,
|
||||
nls.localize('hideActivitBar', "Hide Activity Bar"),
|
||||
|
|
|
@ -365,7 +365,7 @@ export abstract class ViewPane extends Pane implements IView {
|
|||
}
|
||||
|
||||
const calculatedTitle = this.calculateTitle(title);
|
||||
this.titleContainer = append(container, $('h3.title', undefined, calculatedTitle));
|
||||
this.titleContainer = append(container, $('h3.title', { title: calculatedTitle }, calculatedTitle));
|
||||
|
||||
if (this._titleDescription) {
|
||||
this.setTitleDescription(this._titleDescription);
|
||||
|
@ -379,6 +379,7 @@ export abstract class ViewPane extends Pane implements IView {
|
|||
const calculatedTitle = this.calculateTitle(title);
|
||||
if (this.titleContainer) {
|
||||
this.titleContainer.textContent = calculatedTitle;
|
||||
this.titleContainer.setAttribute('title', calculatedTitle);
|
||||
}
|
||||
|
||||
if (this.iconContainer) {
|
||||
|
@ -393,9 +394,10 @@ export abstract class ViewPane extends Pane implements IView {
|
|||
private setTitleDescription(description: string | undefined) {
|
||||
if (this.titleDescriptionContainer) {
|
||||
this.titleDescriptionContainer.textContent = description ?? '';
|
||||
this.titleDescriptionContainer.setAttribute('title', description ?? '');
|
||||
}
|
||||
else if (description && this.titleContainer) {
|
||||
this.titleDescriptionContainer = after(this.titleContainer, $('span.description', undefined, description));
|
||||
this.titleDescriptionContainer = after(this.titleContainer, $('span.description', { title: description }, description));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mark } from 'vs/base/common/performance';
|
||||
import { domContentLoaded, addDisposableListener, EventType, EventHelper } from 'vs/base/browser/dom';
|
||||
import { domContentLoaded, addDisposableListener, EventType, EventHelper, detectFullscreen, addDisposableThrottledListener } from 'vs/base/browser/dom';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { ILogService, ConsoleLogService, MultiplexLogService } from 'vs/platform/log/common/log';
|
||||
import { ConsoleLogInAutomationService } from 'vs/platform/log/browser/log';
|
||||
|
@ -25,8 +25,8 @@ import { Schemas } from 'vs/base/common/network';
|
|||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import * as browser from 'vs/base/browser/browser';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { setFullscreen } from 'vs/base/browser/browser';
|
||||
import { isIOS, isMacintosh } from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWorkspaceInitializationPayload } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
|
||||
|
@ -58,6 +58,14 @@ class BrowserMain extends Disposable {
|
|||
private readonly configuration: IWorkbenchConstructionOptions
|
||||
) {
|
||||
super();
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
private init(): void {
|
||||
|
||||
// Browser config
|
||||
setFullscreen(!!detectFullscreen());
|
||||
}
|
||||
|
||||
async open(): Promise<IWorkbench> {
|
||||
|
@ -99,7 +107,7 @@ class BrowserMain extends Disposable {
|
|||
private registerListeners(workbench: Workbench, storageService: BrowserStorageService): void {
|
||||
|
||||
// Layout
|
||||
const viewport = platform.isIOS && (<any>window).visualViewport ? (<any>window).visualViewport /** Visual viewport */ : window /** Layout viewport */;
|
||||
const viewport = isIOS && window.visualViewport ? window.visualViewport /** Visual viewport */ : window /** Layout viewport */;
|
||||
this._register(addDisposableListener(viewport, EventType.RESIZE, () => workbench.layout()));
|
||||
|
||||
// Prevent the back/forward gestures in macOS
|
||||
|
@ -123,16 +131,15 @@ class BrowserMain extends Disposable {
|
|||
}));
|
||||
this._register(workbench.onShutdown(() => this.dispose()));
|
||||
|
||||
// Fullscreen
|
||||
// Fullscreen (Browser)
|
||||
[EventType.FULLSCREEN_CHANGE, EventType.WK_FULLSCREEN_CHANGE].forEach(event => {
|
||||
this._register(addDisposableListener(document, event, () => {
|
||||
if (document.fullscreenElement || (<any>document).webkitFullscreenElement || (<any>document).webkitIsFullScreen) {
|
||||
browser.setFullscreen(true);
|
||||
} else {
|
||||
browser.setFullscreen(false);
|
||||
}
|
||||
}));
|
||||
this._register(addDisposableListener(document, event, () => setFullscreen(!!detectFullscreen())));
|
||||
});
|
||||
|
||||
// Fullscreen (Native)
|
||||
this._register(addDisposableThrottledListener(viewport, EventType.RESIZE, () => {
|
||||
setFullscreen(!!detectFullscreen());
|
||||
}, undefined, isMacintosh ? 2000 /* adjust for macOS animation */ : 800 /* can be throttled */));
|
||||
}
|
||||
|
||||
private async initServices(): Promise<{ serviceCollection: ServiceCollection, logService: ILogService, storageService: BrowserStorageService }> {
|
||||
|
@ -214,7 +221,7 @@ class BrowserMain extends Disposable {
|
|||
// Initialize required resources - settings & global state
|
||||
await userDataInitializationService.initializeRequiredResources();
|
||||
|
||||
// Important Reload only local user configuration after initializing
|
||||
// Important: Reload only local user configuration after initializing
|
||||
// Reloading complete configuraiton blocks workbench until remote configuration is loaded.
|
||||
await configurationService.reloadLocalUserConfiguration();
|
||||
mark('didInitRequiredUserData');
|
||||
|
|
|
@ -51,7 +51,7 @@ export class BulkCellEdits {
|
|||
// apply edits
|
||||
const edits = group.map(entry => entry.cellEdit);
|
||||
this._notebookService.transformEditsOutputs(ref.object.notebook, edits);
|
||||
ref.object.notebook.applyEdit(ref.object.notebook.versionId, edits, true, undefined, () => undefined);
|
||||
ref.object.notebook.applyEdits(ref.object.notebook.versionId, edits, true, undefined, () => undefined);
|
||||
ref.dispose();
|
||||
|
||||
this._progress.report(undefined);
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as os from 'os';
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
|
@ -22,6 +20,8 @@ import { ITextModel } from 'vs/editor/common/model';
|
|||
import { Constants } from 'vs/base/common/uint';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { join } from 'vs/base/common/path';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
class StartDebugTextMate extends Action {
|
||||
|
||||
|
@ -37,7 +37,8 @@ class StartDebugTextMate extends Action {
|
|||
@IModelService private readonly _modelService: IModelService,
|
||||
@IEditorService private readonly _editorService: IEditorService,
|
||||
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
|
||||
@IHostService private readonly _hostService: IHostService
|
||||
@IHostService private readonly _hostService: IHostService,
|
||||
@IWorkbenchEnvironmentService private readonly _environmentService: INativeWorkbenchEnvironmentService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
@ -59,7 +60,7 @@ class StartDebugTextMate extends Action {
|
|||
}
|
||||
|
||||
public async run(): Promise<any> {
|
||||
const pathInTemp = join(os.tmpdir(), `vcode-tm-log-${generateUuid()}.txt`);
|
||||
const pathInTemp = join(this._environmentService.tmpDir.fsPath, `vcode-tm-log-${generateUuid()}.txt`);
|
||||
const logger = createRotatingLogger(`tm-log`, pathInTemp, 1024 * 1024 * 30, 1);
|
||||
const model = this._getOrCreateModel();
|
||||
const append = (str: string) => {
|
||||
|
|
|
@ -13,7 +13,7 @@ import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } fr
|
|||
import { Extensions as EditorInputExtensions, IEditorInputFactoryRegistry } from 'vs/workbench/common/editor';
|
||||
import { CustomEditorInputFactory } from 'vs/workbench/contrib/customEditor/browser/customEditorInputFactory';
|
||||
import { ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
|
||||
import { WebviewEditor } from 'vs/workbench/contrib/webview/browser/webviewEditor';
|
||||
import { WebviewEditor } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditor';
|
||||
import { CustomEditorInput } from './customEditorInput';
|
||||
import { CustomEditorContribution, CustomEditorService } from './customEditors';
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import { IUndoRedoService } from 'vs/platform/undoRedo/common/undoRedo';
|
|||
import { GroupIdentifier, IEditorInput, IRevertOptions, ISaveOptions, Verbosity } from 'vs/workbench/common/editor';
|
||||
import { ICustomEditorModel, ICustomEditorService } from 'vs/workbench/contrib/customEditor/common/customEditor';
|
||||
import { IWebviewService, WebviewOverlay } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { IWebviewWorkbenchService, LazilyResolvedWebviewEditorInput } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { CustomEditorInput } from 'vs/workbench/contrib/customEditor/browser/customEditorInput';
|
||||
import { IWebviewService, WebviewExtensionDescription, WebviewContentPurpose } from 'vs/workbench/contrib/webview/browser/webview';
|
||||
import { reviveWebviewExtensionDescription, SerializedWebview, WebviewEditorInputFactory, DeserializedWebview } from 'vs/workbench/contrib/webview/browser/webviewEditorInputFactory';
|
||||
import { IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewWorkbenchService';
|
||||
import { reviveWebviewExtensionDescription, SerializedWebview, WebviewEditorInputFactory, DeserializedWebview } from 'vs/workbench/contrib/webviewPanel/browser/webviewEditorInputFactory';
|
||||
import { IWebviewWorkbenchService, WebviewInputOptions } from 'vs/workbench/contrib/webviewPanel/browser/webviewWorkbenchService';
|
||||
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
|
||||
|
||||
export interface CustomDocumentBackupData {
|
||||
|
|
|
@ -95,8 +95,12 @@ export function prepareCommand(shell: string, args: string[], cwd?: string, env?
|
|||
}
|
||||
|
||||
let quote: (s: string) => string;
|
||||
|
||||
// cancel the current input (to avoid executing the command accidentally)
|
||||
let command = '\u0003'; // Control-C
|
||||
|
||||
// begin command with a space to avoid polluting shell history
|
||||
let command = ' ';
|
||||
command += ' ';
|
||||
|
||||
switch (shellType) {
|
||||
|
||||
|
|
|
@ -353,8 +353,6 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
|
|||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IEditorGroupsService private readonly editorGroupService: IEditorGroupsService,
|
||||
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
|
||||
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IExtensionGalleryService private readonly extensionGalleryService: IExtensionGalleryService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
|
@ -534,9 +532,6 @@ export class ExtensionsViewPaneContainer extends ViewPaneContainer implements IE
|
|||
new SubmenuAction('workbench.extensions.action.filterExtensionsByCategory', localize('filter by category', "Category"), EXTENSION_CATEGORIES.map(category => this.instantiationService.createInstance(SearchCategoryAction, `extensions.actions.searchByCategory.${category}`, category, category))),
|
||||
new Separator(),
|
||||
];
|
||||
if (this.extensionManagementServerService.webExtensionManagementServer || !this.environmentService.isBuilt) {
|
||||
galleryFilterActions.splice(4, 0, this.instantiationService.createInstance(PredefinedExtensionFilterAction, 'extensions.filter.web', localize('web filter', "Web"), '@web'));
|
||||
}
|
||||
filterActions.splice(0, 0, ...galleryFilterActions);
|
||||
filterActions.push(...[
|
||||
new Separator(),
|
||||
|
|
|
@ -1163,7 +1163,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
|||
return changed;
|
||||
}
|
||||
|
||||
private _activityCallBack: (() => void) | null = null;
|
||||
private _activityCallBack: ((value: void) => void) | null = null;
|
||||
private updateActivity(): void {
|
||||
if ((this.localExtensions && this.localExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))
|
||||
|| (this.remoteExtensions && this.remoteExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))
|
||||
|
|
|
@ -37,7 +37,7 @@ import { randomPort } from 'vs/base/node/ports';
|
|||
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { ExtensionIdentifier, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { SlowExtensionAction } from 'vs/workbench/contrib/extensions/electron-browser/extensionsSlowActions';
|
||||
|
@ -408,28 +408,28 @@ export class RuntimeExtensionsEditor extends EditorPane {
|
|||
clearNode(data.msgContainer);
|
||||
|
||||
if (this._extensionHostProfileService.getUnresponsiveProfile(element.description.identifier)) {
|
||||
const el = $('span', undefined, ...renderCodiconsAsElement(` $(alert) Unresponsive`));
|
||||
const el = $('span', undefined, ...renderCodicons(` $(alert) Unresponsive`));
|
||||
el.title = nls.localize('unresponsive.title', "Extension has caused the extension host to freeze.");
|
||||
data.msgContainer.appendChild(el);
|
||||
}
|
||||
|
||||
if (isNonEmptyArray(element.status.runtimeErrors)) {
|
||||
const el = $('span', undefined, ...renderCodiconsAsElement(`$(bug) ${nls.localize('errors', "{0} uncaught errors", element.status.runtimeErrors.length)}`));
|
||||
const el = $('span', undefined, ...renderCodicons(`$(bug) ${nls.localize('errors', "{0} uncaught errors", element.status.runtimeErrors.length)}`));
|
||||
data.msgContainer.appendChild(el);
|
||||
}
|
||||
|
||||
if (element.status.messages && element.status.messages.length > 0) {
|
||||
const el = $('span', undefined, ...renderCodiconsAsElement(`$(alert) ${element.status.messages[0].message}`));
|
||||
const el = $('span', undefined, ...renderCodicons(`$(alert) ${element.status.messages[0].message}`));
|
||||
data.msgContainer.appendChild(el);
|
||||
}
|
||||
|
||||
if (element.description.extensionLocation.scheme !== 'file') {
|
||||
const el = $('span', undefined, ...renderCodiconsAsElement(`$(remote) ${element.description.extensionLocation.authority}`));
|
||||
const el = $('span', undefined, ...renderCodicons(`$(remote) ${element.description.extensionLocation.authority}`));
|
||||
data.msgContainer.appendChild(el);
|
||||
|
||||
const hostLabel = this._labelService.getHostLabel(Schemas.vscodeRemote, this._environmentService.configuration.remoteAuthority);
|
||||
if (hostLabel) {
|
||||
reset(el, ...renderCodiconsAsElement(`$(remote) ${hostLabel}`));
|
||||
reset(el, ...renderCodicons(`$(remote) ${hostLabel}`));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ import { ExtensionTipsService } from 'vs/platform/extensionManagement/node/exten
|
|||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { TestLifecycleService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
|
||||
|
||||
let instantiationService: TestInstantiationService;
|
||||
let installEvent: Emitter<InstallExtensionEvent>,
|
||||
|
@ -99,7 +100,7 @@ async function setupTest() {
|
|||
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
|
||||
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', id: 'vscode-local' };
|
||||
constructor() {
|
||||
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(ILabelService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IProductService), instantiationService.get(IConfigurationService), instantiationService.get(ILogService));
|
||||
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(ILabelService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IProductService), instantiationService.get(IConfigurationService), instantiationService.get(ILogService), instantiationService.get(IWorkbenchEnvironmentService) as INativeWorkbenchEnvironmentService);
|
||||
}
|
||||
get localExtensionManagementServer(): IExtensionManagementServer { return this.#localExtensionManagementServer; }
|
||||
set localExtensionManagementServer(server: IExtensionManagementServer) { }
|
||||
|
|
|
@ -45,6 +45,8 @@ import { IMenuService } from 'vs/platform/actions/common/actions';
|
|||
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
|
||||
import { IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
|
||||
|
||||
suite('ExtensionsListView Tests', () => {
|
||||
|
||||
|
@ -104,7 +106,7 @@ suite('ExtensionsListView Tests', () => {
|
|||
instantiationService.stub(IExtensionManagementServerService, new class extends ExtensionManagementServerService {
|
||||
#localExtensionManagementServer: IExtensionManagementServer = { extensionManagementService: instantiationService.get(IExtensionManagementService), label: 'local', id: 'vscode-local' };
|
||||
constructor() {
|
||||
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(ILabelService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IProductService), instantiationService.get(IConfigurationService), instantiationService.get(ILogService));
|
||||
super(instantiationService.get(ISharedProcessService), instantiationService.get(IRemoteAgentService), instantiationService.get(ILabelService), instantiationService.get(IExtensionGalleryService), instantiationService.get(IProductService), instantiationService.get(IConfigurationService), instantiationService.get(ILogService), instantiationService.get(IWorkbenchEnvironmentService) as INativeWorkbenchEnvironmentService);
|
||||
}
|
||||
get localExtensionManagementServer(): IExtensionManagementServer { return this.#localExtensionManagementServer; }
|
||||
set localExtensionManagementServer(server: IExtensionManagementServer) { }
|
||||
|
|
|
@ -22,7 +22,7 @@ import { AutoSaveAfterShortDelayContext } from 'vs/workbench/services/filesConfi
|
|||
import { ResourceContextKey } from 'vs/workbench/common/resources';
|
||||
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { DirtyWorkingCopiesContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { DirtyWorkingCopiesContext, EmptyWorkspaceSupportContext, WorkspaceFolderCountContext } from 'vs/workbench/browser/contextkeys';
|
||||
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { OpenFileFolderAction, OpenFileAction, OpenFolderAction, OpenWorkspaceAction } from 'vs/workbench/browser/actions/workspaceActions';
|
||||
|
@ -42,7 +42,7 @@ registry.registerWorkbenchAction(SyncActionDescriptor.from(CollapseExplorerView)
|
|||
registry.registerWorkbenchAction(SyncActionDescriptor.from(RefreshExplorerView), 'File: Refresh Explorer', category.value);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(CompareWithClipboardAction, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_C) }), 'File: Compare Active File with Clipboard', category.value);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ToggleAutoSaveAction), 'File: Toggle Auto Save', category.value);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowOpenedFileInNewWindow, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_O) }), 'File: Open Active File in New Window', category.value);
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(ShowOpenedFileInNewWindow, { primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.KEY_O) }), 'File: Open Active File in New Window', category.value, EmptyWorkspaceSupportContext);
|
||||
|
||||
const workspacesCategory = nls.localize('workspaces', "Workspaces");
|
||||
registry.registerWorkbenchAction(SyncActionDescriptor.from(OpenWorkspaceAction), 'Workspaces: Open Workspace...', workspacesCategory);
|
||||
|
|
|
@ -121,7 +121,7 @@ class DefaultFormatter extends Disposable implements IWorkbenchContribution {
|
|||
if (silent) {
|
||||
// don't wait when formatting happens without interaction
|
||||
// but pick some formatter...
|
||||
resolve(formatter[0]);
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@ import * as nls from 'vs/nls';
|
|||
import product from 'vs/platform/product/common/product';
|
||||
import { SyncActionDescriptor, ICommandAction, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IWorkbenchActionRegistry, Extensions } from 'vs/workbench/common/actions';
|
||||
import { ReportPerformanceIssueUsingReporterAction, OpenProcessExplorer } from 'vs/workbench/contrib/issue/electron-browser/issueActions';
|
||||
import { ReportPerformanceIssueUsingReporterAction, OpenProcessExplorer } from 'vs/workbench/contrib/issue/electron-sandbox/issueActions';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issueService';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-sandbox/issue';
|
||||
import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-sandbox/issueService';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IssueReporterData } from 'vs/platform/issue/common/issue';
|
||||
import { IIssueService } from 'vs/platform/issue/electron-sandbox/issue';
|
|
@ -6,7 +6,7 @@
|
|||
import { Action } from 'vs/base/common/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IssueType } from 'vs/platform/issue/common/issue';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-sandbox/issue';
|
||||
|
||||
export class OpenProcessExplorer extends Action {
|
||||
static readonly ID = 'workbench.action.openProcessExplorer';
|
|
@ -11,11 +11,11 @@ import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
|||
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { getZoomLevel } from 'vs/base/browser/browser';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-sandbox/issue';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-sandbox/environmentService';
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { platform } from 'process';
|
||||
import { platform, PlatformToString } from 'vs/base/common/platform';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export class WorkbenchIssueService implements IWorkbenchIssueService {
|
||||
|
@ -71,7 +71,7 @@ export class WorkbenchIssueService implements IWorkbenchIssueService {
|
|||
hoverForeground: getColor(theme, listHoverForeground),
|
||||
highlightForeground: getColor(theme, listHighlightForeground),
|
||||
},
|
||||
platform,
|
||||
platform: PlatformToString(platform),
|
||||
applicationName: this.productService.applicationName
|
||||
};
|
||||
return this.issueService.openProcessExplorer(data);
|
|
@ -511,27 +511,33 @@ export async function changeCellToKind(kind: CellKind, context: INotebookCellAct
|
|||
return null;
|
||||
}
|
||||
|
||||
if (!notebookEditor.viewModel) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const text = cell.getText();
|
||||
if (!notebookEditor.insertNotebookCell(cell, kind, 'below', text)) {
|
||||
return null;
|
||||
}
|
||||
const idx = notebookEditor.viewModel.getCellIndex(cell);
|
||||
notebookEditor.viewModel.notebookDocument.applyEdits(notebookEditor.viewModel.notebookDocument.versionId, [
|
||||
{
|
||||
editType: CellEditType.Replace,
|
||||
index: idx,
|
||||
count: 1,
|
||||
cells: [{
|
||||
cellKind: kind,
|
||||
source: text,
|
||||
language: language!,
|
||||
outputs: cell.model.outputs,
|
||||
metadata: cell.metadata,
|
||||
}]
|
||||
}
|
||||
], true, undefined, () => undefined, true);
|
||||
const newCell = notebookEditor.viewModel.viewCells[idx];
|
||||
|
||||
const idx = notebookEditor.viewModel?.getCellIndex(cell);
|
||||
if (typeof idx !== 'number') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const newCell = notebookEditor.viewModel?.viewCells[idx + 1];
|
||||
if (!newCell) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (language) {
|
||||
newCell.model.language = language;
|
||||
}
|
||||
|
||||
notebookEditor.focusNotebookCell(newCell, cell.editState === CellEditState.Editing ? 'editor' : 'container');
|
||||
notebookEditor.deleteNotebookCell(cell);
|
||||
|
||||
return newCell;
|
||||
}
|
||||
|
@ -1301,10 +1307,10 @@ registerAction2(class extends NotebookCellAction {
|
|||
return;
|
||||
}
|
||||
|
||||
editor.viewModel.notebookDocument.applyEdit(editor.viewModel.notebookDocument.versionId, [{ editType: CellEditType.Output, index, outputs: [] }], true, undefined, () => undefined);
|
||||
editor.viewModel.notebookDocument.applyEdits(editor.viewModel.notebookDocument.versionId, [{ editType: CellEditType.Output, index, outputs: [] }], true, undefined, () => undefined);
|
||||
|
||||
if (context.cell.metadata && context.cell.metadata?.runState !== NotebookCellRunState.Running) {
|
||||
context.notebookEditor.viewModel!.notebookDocument.applyEdit(context.notebookEditor.viewModel!.notebookDocument.versionId, [{
|
||||
context.notebookEditor.viewModel!.notebookDocument.applyEdits(context.notebookEditor.viewModel!.notebookDocument.versionId, [{
|
||||
editType: CellEditType.Metadata, index, metadata: {
|
||||
...context.cell.metadata,
|
||||
runState: NotebookCellRunState.Idle,
|
||||
|
@ -1388,11 +1394,11 @@ export class ChangeCellLanguageAction extends NotebookCellAction {
|
|||
if (newCell) {
|
||||
context.notebookEditor.focusNotebookCell(newCell, 'editor');
|
||||
}
|
||||
} else if (selection.languageId !== 'markdown' && context.cell?.language === 'markdown') {
|
||||
} else if (selection.languageId !== 'markdown' && context.cell?.cellKind === CellKind.Markdown) {
|
||||
await changeCellToKind(CellKind.Code, { cell: context.cell, notebookEditor: context.notebookEditor }, selection.languageId);
|
||||
} else {
|
||||
const index = context.notebookEditor.viewModel!.notebookDocument.cells.indexOf(context.cell.model);
|
||||
context.notebookEditor.viewModel!.notebookDocument.applyEdit(
|
||||
context.notebookEditor.viewModel!.notebookDocument.applyEdits(
|
||||
context.notebookEditor.viewModel!.notebookDocument.versionId,
|
||||
[{ editType: CellEditType.CellLanguage, index, language: selection.languageId }],
|
||||
true, undefined, () => undefined
|
||||
|
@ -1443,7 +1449,7 @@ registerAction2(class extends NotebookAction {
|
|||
return;
|
||||
}
|
||||
|
||||
editor.viewModel.notebookDocument.applyEdit(editor.viewModel.notebookDocument.versionId,
|
||||
editor.viewModel.notebookDocument.applyEdits(editor.viewModel.notebookDocument.versionId,
|
||||
editor.viewModel.notebookDocument.cells.map((cell, index) => ({
|
||||
editType: CellEditType.Output, index, outputs: []
|
||||
})), true, undefined, () => undefined);
|
||||
|
@ -1580,7 +1586,7 @@ abstract class ChangeNotebookCellMetadataAction extends NotebookCellAction {
|
|||
return;
|
||||
}
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [{ editType: CellEditType.Metadata, index, metadata: { ...context.cell.metadata, ...this.getMetadataDelta() } }], true, undefined, () => undefined);
|
||||
textModel.applyEdits(textModel.versionId, [{ editType: CellEditType.Metadata, index, metadata: { ...context.cell.metadata, ...this.getMetadataDelta() } }], true, undefined, () => undefined);
|
||||
}
|
||||
|
||||
abstract getMetadataDelta(): NotebookCellMetadata;
|
||||
|
|
|
@ -12,7 +12,7 @@ import { CellDiffRenderTemplate, CellDiffViewModelLayoutChangeEvent, DIFF_CELL_M
|
|||
import { EDITOR_BOTTOM_PADDING, EDITOR_TOP_PADDING } from 'vs/workbench/contrib/notebook/browser/constants';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { DiffEditorWidget } from 'vs/editor/browser/widget/diffEditorWidget';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { format } from 'vs/base/common/jsonFormatter';
|
||||
|
@ -194,9 +194,9 @@ class PropertyHeader extends Disposable {
|
|||
|
||||
private _updateFoldingIcon() {
|
||||
if (this.accessor.getFoldingState(this.cell) === PropertyFoldingState.Collapsed) {
|
||||
DOM.reset(this._foldingIndicator, ...renderCodiconsAsElement('$(chevron-right)'));
|
||||
DOM.reset(this._foldingIndicator, ...renderCodicons('$(chevron-right)'));
|
||||
} else {
|
||||
DOM.reset(this._foldingIndicator, ...renderCodiconsAsElement('$(chevron-down)'));
|
||||
DOM.reset(this._foldingIndicator, ...renderCodicons('$(chevron-down)'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -473,7 +473,7 @@ abstract class AbstractCellRenderer extends Disposable {
|
|||
|
||||
if (newLangauge !== undefined && newLangauge !== this.cell.modified!.language) {
|
||||
const index = this.notebookEditor.textModel!.cells.indexOf(this.cell.modified!);
|
||||
this.notebookEditor.textModel!.applyEdit(
|
||||
this.notebookEditor.textModel!.applyEdits(
|
||||
this.notebookEditor.textModel!.versionId,
|
||||
[{ editType: CellEditType.CellLanguage, index, language: newLangauge }],
|
||||
true,
|
||||
|
@ -488,7 +488,7 @@ abstract class AbstractCellRenderer extends Disposable {
|
|||
return;
|
||||
}
|
||||
|
||||
this.notebookEditor.textModel!.applyEdit(this.notebookEditor.textModel!.versionId, [
|
||||
this.notebookEditor.textModel!.applyEdits(this.notebookEditor.textModel!.versionId, [
|
||||
{ editType: CellEditType.Metadata, index, metadata: result }
|
||||
], true, undefined, () => undefined);
|
||||
} catch {
|
||||
|
|
|
@ -290,7 +290,7 @@ export class NotebookContribution extends Disposable implements IWorkbenchContri
|
|||
private onEditorOpening2(originalInput: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup): IOpenEditorOverride | undefined {
|
||||
|
||||
let id = typeof options?.override === 'string' ? options.override : undefined;
|
||||
if (id === undefined && originalInput.isUntitled()) {
|
||||
if (id === undefined && originalInput.resource?.scheme === Schemas.untitled) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IListRenderer, IListVirtualDelegate } from 'vs/base/browser/ui/list/lis
|
|||
import { ProgressBar } from 'vs/base/browser/ui/progressbar/progressbar';
|
||||
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
|
||||
import { IAction } from 'vs/base/common/actions';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
|
@ -340,11 +340,11 @@ abstract class AbstractCellRenderer {
|
|||
}
|
||||
|
||||
if (templateData.currentRenderedCell.metadata?.inputCollapsed) {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Metadata, index, metadata: { ...templateData.currentRenderedCell.metadata, inputCollapsed: false } }
|
||||
], true, undefined, () => undefined);
|
||||
} else if (templateData.currentRenderedCell.metadata?.outputCollapsed) {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Metadata, index, metadata: { ...templateData.currentRenderedCell.metadata, outputCollapsed: false } }
|
||||
], true, undefined, () => undefined);
|
||||
}
|
||||
|
@ -352,7 +352,7 @@ abstract class AbstractCellRenderer {
|
|||
}
|
||||
|
||||
protected setupCollapsedPart(container: HTMLElement): { collapsedPart: HTMLElement, expandButton: HTMLElement } {
|
||||
const collapsedPart = DOM.append(container, $('.cell.cell-collapsed-part', undefined, ...renderCodiconsAsElement('$(unfold)')));
|
||||
const collapsedPart = DOM.append(container, $('.cell.cell-collapsed-part', undefined, ...renderCodicons('$(unfold)')));
|
||||
const expandButton = collapsedPart.querySelector('.codicon') as HTMLElement;
|
||||
const keybinding = this.keybindingService.lookupKeybinding(EXPAND_CELL_CONTENT_COMMAND_ID);
|
||||
let title = localize('cellExpandButtonLabel', "Expand");
|
||||
|
@ -960,11 +960,11 @@ export class RunStateRenderer {
|
|||
}
|
||||
|
||||
if (runState === NotebookCellRunState.Success) {
|
||||
DOM.reset(this.element, ...renderCodiconsAsElement('$(check)'));
|
||||
DOM.reset(this.element, ...renderCodicons('$(check)'));
|
||||
} else if (runState === NotebookCellRunState.Error) {
|
||||
DOM.reset(this.element, ...renderCodiconsAsElement('$(error)'));
|
||||
DOM.reset(this.element, ...renderCodicons('$(error)'));
|
||||
} else if (runState === NotebookCellRunState.Running) {
|
||||
DOM.reset(this.element, ...renderCodiconsAsElement('$(sync~spin)'));
|
||||
DOM.reset(this.element, ...renderCodicons('$(sync~spin)'));
|
||||
|
||||
this.spinnerTimer = setTimeout(() => {
|
||||
this.spinnerTimer = undefined;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { MenuItemAction } from 'vs/platform/actions/common/actions';
|
|||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
|
||||
export class CodiconActionViewItem extends MenuEntryActionViewItem {
|
||||
constructor(
|
||||
|
@ -22,7 +22,7 @@ export class CodiconActionViewItem extends MenuEntryActionViewItem {
|
|||
}
|
||||
updateLabel(): void {
|
||||
if (this.options.label && this.label) {
|
||||
DOM.reset(this.label, ...renderCodiconsAsElement(this._commandAction.label ?? ''));
|
||||
DOM.reset(this.label, ...renderCodicons(this._commandAction.label ?? ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { raceCancellation } from 'vs/base/common/async';
|
||||
import { CancellationTokenSource } from 'vs/base/common/cancellation';
|
||||
import { renderCodiconsAsElement } from 'vs/base/browser/codicons';
|
||||
import { renderCodicons } from 'vs/base/browser/codicons';
|
||||
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
|
@ -315,10 +315,10 @@ export class StatefulMarkdownCell extends Disposable {
|
|||
this.templateData.foldingIndicator.innerText = '';
|
||||
break;
|
||||
case CellFoldingState.Collapsed:
|
||||
DOM.reset(this.templateData.foldingIndicator, ...renderCodiconsAsElement('$(chevron-right)'));
|
||||
DOM.reset(this.templateData.foldingIndicator, ...renderCodicons('$(chevron-right)'));
|
||||
break;
|
||||
case CellFoldingState.Expanded:
|
||||
DOM.reset(this.templateData.foldingIndicator, ...renderCodiconsAsElement('$(chevron-down)'));
|
||||
DOM.reset(this.templateData.foldingIndicator, ...renderCodicons('$(chevron-down)'));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -312,12 +312,12 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
if (change.kind === NotebookCellsChangeType.ModelChange || change.kind === NotebookCellsChangeType.Initialize) {
|
||||
changes = change.changes;
|
||||
compute(changes, e.synchronous);
|
||||
return;
|
||||
continue;
|
||||
} else if (change.kind === NotebookCellsChangeType.Move) {
|
||||
compute([[change.index, change.length, []]], e.synchronous);
|
||||
compute([[change.newIdx, 0, change.cells]], e.synchronous);
|
||||
} else {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
@ -625,7 +625,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
|
||||
createCell(index: number, source: string, language: string, type: CellKind, metadata: NotebookCellMetadata | undefined, outputs: IProcessedOutput[], synchronous: boolean, pushUndoStop: boolean = true, previouslyFocused: ICellViewModel[] = []): CellViewModel {
|
||||
const beforeSelections = previouslyFocused.map(e => e.handle);
|
||||
this._notebook.applyEdit(this._notebook.versionId, [
|
||||
this._notebook.applyEdits(this._notebook.versionId, [
|
||||
{
|
||||
editType: CellEditType.Replace,
|
||||
index,
|
||||
|
@ -663,7 +663,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
}
|
||||
}
|
||||
|
||||
this._notebook.applyEdit(this._notebook.versionId, [
|
||||
this._notebook.applyEdits(this._notebook.versionId, [
|
||||
{
|
||||
editType: CellEditType.Replace,
|
||||
index: index,
|
||||
|
@ -691,7 +691,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
return false;
|
||||
}
|
||||
|
||||
this._notebook.applyEdit(this._notebook.versionId, [
|
||||
this._notebook.applyEdits(this._notebook.versionId, [
|
||||
{
|
||||
editType: CellEditType.Move,
|
||||
index,
|
||||
|
@ -785,7 +785,7 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
const editorSelections = cell.getSelections();
|
||||
const language = cell.language;
|
||||
const kind = cell.cellKind;
|
||||
this._notebook.applyEdit(this._notebook.versionId, [
|
||||
this._notebook.applyEdits(this._notebook.versionId, [
|
||||
{
|
||||
editType: CellEditType.CellContent,
|
||||
index,
|
||||
|
@ -957,11 +957,15 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
|
||||
getEditorViewState(): INotebookEditorViewState {
|
||||
const editingCells: { [key: number]: boolean } = {};
|
||||
this._viewCells.filter(cell => cell.editState === CellEditState.Editing).forEach(cell => editingCells[cell.model.handle] = true);
|
||||
this._viewCells.forEach((cell, i) => {
|
||||
if (cell.editState === CellEditState.Editing) {
|
||||
editingCells[i] = true;
|
||||
}
|
||||
});
|
||||
const editorViewStates: { [key: number]: editorCommon.ICodeEditorViewState } = {};
|
||||
this._viewCells.map(cell => ({ handle: cell.model.handle, state: cell.saveEditorViewState() })).forEach(viewState => {
|
||||
this._viewCells.map(cell => ({ handle: cell.model.handle, state: cell.saveEditorViewState() })).forEach((viewState, i) => {
|
||||
if (viewState.state) {
|
||||
editorViewStates[viewState.handle] = viewState.state;
|
||||
editorViewStates[i] = viewState.state;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -977,8 +981,8 @@ export class NotebookViewModel extends Disposable implements EditorFoldingStateD
|
|||
}
|
||||
|
||||
this._viewCells.forEach((cell, index) => {
|
||||
const isEditing = viewState.editingCells && viewState.editingCells[cell.handle];
|
||||
const editorViewState = viewState.editorViewStates && viewState.editorViewStates[cell.handle];
|
||||
const isEditing = viewState.editingCells && viewState.editingCells[index];
|
||||
const editorViewState = viewState.editorViewStates && viewState.editorViewStates[index];
|
||||
|
||||
cell.editState = isEditing ? CellEditState.Editing : CellEditState.Preview;
|
||||
const cellHeight = viewState.cellTotalHeights ? viewState.cellTotalHeights[index] : undefined;
|
||||
|
|
|
@ -291,7 +291,7 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
this._operationManager.pushStackElement(label, selectionState);
|
||||
}
|
||||
|
||||
applyEdit(modelVersionId: number, rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: number[] | undefined, endSelectionsComputer: () => number[] | undefined, computeUndoRedo: boolean = true): boolean {
|
||||
applyEdits(modelVersionId: number, rawEdits: ICellEditOperation[], synchronous: boolean, beginSelectionState: number[] | undefined, endSelectionsComputer: () => number[] | undefined, computeUndoRedo: boolean = true): boolean {
|
||||
if (modelVersionId !== this._versionId) {
|
||||
return false;
|
||||
}
|
||||
|
@ -478,7 +478,26 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
}
|
||||
|
||||
private _updateNotebookMetadata(metadata: NotebookDocumentMetadata, computeUndoRedo: boolean) {
|
||||
const oldMetadata = this.metadata;
|
||||
this.metadata = metadata;
|
||||
|
||||
if (computeUndoRedo) {
|
||||
const that = this;
|
||||
this._operationManager.pushEditOperation(new class implements IResourceUndoRedoElement {
|
||||
readonly type: UndoRedoElementType.Resource = UndoRedoElementType.Resource;
|
||||
get resource() {
|
||||
return that.uri;
|
||||
}
|
||||
readonly label = 'Update Notebook Metadata';
|
||||
undo() {
|
||||
that._updateNotebookMetadata(oldMetadata, false);
|
||||
}
|
||||
redo() {
|
||||
that._updateNotebookMetadata(metadata, false);
|
||||
}
|
||||
}(), undefined, undefined);
|
||||
}
|
||||
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeDocumentMetadata, metadata: this.metadata, transient: false }, true);
|
||||
}
|
||||
|
||||
|
@ -565,11 +584,31 @@ export class NotebookTextModel extends Disposable implements INotebookTextModel
|
|||
|
||||
private _changeCellLanguage(handle: number, languageId: string, computeUndoRedo: boolean) {
|
||||
const cell = this._mapping.get(handle);
|
||||
if (cell && cell.language !== languageId) {
|
||||
cell.language = languageId;
|
||||
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeLanguage, index: this._cells.indexOf(cell), language: languageId, transient: false }, true);
|
||||
if (!cell || cell.language === languageId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldLanguage = cell.language;
|
||||
cell.language = languageId;
|
||||
|
||||
if (computeUndoRedo) {
|
||||
const that = this;
|
||||
this._operationManager.pushEditOperation(new class implements IResourceUndoRedoElement {
|
||||
readonly type: UndoRedoElementType.Resource = UndoRedoElementType.Resource;
|
||||
get resource() {
|
||||
return that.uri;
|
||||
}
|
||||
readonly label = 'Update Cell Language';
|
||||
undo() {
|
||||
that._changeCellLanguage(cell.handle, oldLanguage, false);
|
||||
}
|
||||
redo() {
|
||||
that._changeCellLanguage(cell.handle, languageId, false);
|
||||
}
|
||||
}(), undefined, undefined);
|
||||
}
|
||||
|
||||
this._eventEmitter.emit({ kind: NotebookCellsChangeType.ChangeLanguage, index: this._cells.indexOf(cell), language: languageId, transient: false }, true);
|
||||
}
|
||||
|
||||
private _spliceNotebookCellOutputs(cellHandle: number, splices: NotebookCellOutputsSplice[], computeUndoRedo: boolean): void {
|
||||
|
|
|
@ -30,18 +30,9 @@ export class NotebookModelReferenceCollection extends ReferenceCollection<Promis
|
|||
super();
|
||||
}
|
||||
|
||||
protected createReferencedObject(key: string, ...args: any[]): Promise<INotebookEditorModel> {
|
||||
const resource = URI.parse(key);
|
||||
|
||||
let [viewType] = args as [string | undefined];
|
||||
if (!viewType) {
|
||||
viewType = this._notebookService.getContributedNotebookProviders(resource)[0]?.id;
|
||||
}
|
||||
if (!viewType) {
|
||||
throw new Error('Missing viewType');
|
||||
}
|
||||
|
||||
const model = this._instantiationService.createInstance(NotebookEditorModel, resource, viewType);
|
||||
protected createReferencedObject(key: string, viewType: string): Promise<INotebookEditorModel> {
|
||||
const uri = URI.parse(key);
|
||||
const model = this._instantiationService.createInstance(NotebookEditorModel, uri, viewType);
|
||||
const promise = model.load();
|
||||
return promise;
|
||||
}
|
||||
|
@ -63,12 +54,26 @@ export class NotebookModelResolverService implements INotebookEditorModelResolve
|
|||
private readonly _data: NotebookModelReferenceCollection;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService instantiationService: IInstantiationService
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@INotebookService private readonly _notebookService: INotebookService
|
||||
) {
|
||||
this._data = instantiationService.createInstance(NotebookModelReferenceCollection);
|
||||
}
|
||||
|
||||
async resolve(resource: URI, viewType?: string): Promise<IReference<INotebookEditorModel>> {
|
||||
|
||||
const existingViewType = this._notebookService.getNotebookTextModel(resource)?.viewType;
|
||||
if (!viewType) {
|
||||
viewType = existingViewType ?? this._notebookService.getContributedNotebookProviders(resource)[0]?.id;
|
||||
}
|
||||
if (!viewType) {
|
||||
throw new Error(`Missing viewType for '${resource}'`);
|
||||
}
|
||||
|
||||
if (existingViewType && existingViewType !== viewType) {
|
||||
throw new Error(`A notebook with view type '${existingViewType}' already exists for '${resource}', CANNOT create another notebook with view type ${viewType}`);
|
||||
}
|
||||
|
||||
const reference = this._data.acquire(resource.toString(), viewType);
|
||||
const model = await reference.object;
|
||||
NotebookModelResolverService._autoReferenceDirtyModel(model, () => this._data.acquire(resource.toString(), viewType));
|
||||
|
|
|
@ -29,7 +29,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => undefined);
|
||||
|
@ -54,7 +54,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 6, 'var f = 6;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => undefined);
|
||||
|
@ -79,7 +79,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 1, cells: [] },
|
||||
], true, undefined, () => undefined);
|
||||
|
@ -102,7 +102,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 3, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => undefined);
|
||||
|
@ -127,7 +127,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => undefined);
|
||||
|
@ -152,7 +152,7 @@ suite('NotebookTextModel', () => {
|
|||
['var d = 4;', 'javascript', CellKind.Code, [], { editable: false }]
|
||||
],
|
||||
(editor, viewModel, textModel) => {
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => undefined);
|
||||
|
||||
|
@ -176,7 +176,7 @@ suite('NotebookTextModel', () => {
|
|||
|
||||
// invalid index 1
|
||||
assert.throws(() => {
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: Number.MAX_VALUE,
|
||||
editType: CellEditType.Output,
|
||||
outputs: []
|
||||
|
@ -185,14 +185,14 @@ suite('NotebookTextModel', () => {
|
|||
|
||||
// invalid index 2
|
||||
assert.throws(() => {
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: -1,
|
||||
editType: CellEditType.Output,
|
||||
outputs: []
|
||||
}], true, undefined, () => undefined);
|
||||
});
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: 0,
|
||||
editType: CellEditType.Output,
|
||||
outputs: [{
|
||||
|
@ -221,7 +221,7 @@ suite('NotebookTextModel', () => {
|
|||
|
||||
// invalid index 1
|
||||
assert.throws(() => {
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: Number.MAX_VALUE,
|
||||
editType: CellEditType.Metadata,
|
||||
metadata: { editable: false }
|
||||
|
@ -230,14 +230,14 @@ suite('NotebookTextModel', () => {
|
|||
|
||||
// invalid index 2
|
||||
assert.throws(() => {
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: -1,
|
||||
editType: CellEditType.Metadata,
|
||||
metadata: { editable: false }
|
||||
}], true, undefined, () => undefined);
|
||||
});
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [{
|
||||
textModel.applyEdits(textModel.versionId, [{
|
||||
index: 0,
|
||||
editType: CellEditType.Metadata,
|
||||
metadata: { editable: false },
|
||||
|
@ -267,7 +267,7 @@ suite('NotebookTextModel', () => {
|
|||
});
|
||||
const version = textModel.versionId;
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{ editType: CellEditType.Replace, index: 1, count: 0, cells: [new TestCell(viewModel.viewType, 5, 'var e = 5;', 'javascript', CellKind.Code, [], textModelService)] },
|
||||
], true, undefined, () => [0]);
|
||||
|
@ -304,7 +304,7 @@ suite('NotebookTextModel', () => {
|
|||
});
|
||||
const version = textModel.versionId;
|
||||
|
||||
textModel.applyEdit(textModel.versionId, [
|
||||
textModel.applyEdits(textModel.versionId, [
|
||||
{ editType: CellEditType.Replace, index: 1, count: 1, cells: [] },
|
||||
{
|
||||
index: 0,
|
||||
|
|
|
@ -19,7 +19,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
|
|||
import { FilterViewPaneContainer } from 'vs/workbench/browser/parts/views/viewsViewlet';
|
||||
import { VIEWLET_ID } from 'vs/workbench/contrib/remote/common/remote.contribution';
|
||||
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IViewDescriptor, IViewsRegistry, Extensions, ViewContainerLocation, IViewContainersRegistry, IViewDescriptorService, IAddedViewDescriptorRef } from 'vs/workbench/common/views';
|
||||
import { IViewDescriptor, IViewsRegistry, Extensions, ViewContainerLocation, IViewContainersRegistry, IViewDescriptorService, IAddedViewDescriptorRef, IViewsService } from 'vs/workbench/common/views';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
|
@ -37,14 +37,14 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
|||
import { ReconnectionWaitEvent, PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
import Severity from 'vs/base/common/severity';
|
||||
import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
import { SwitchRemoteViewItem, SwitchRemoteAction } from 'vs/workbench/contrib/remote/browser/explorerViewItems';
|
||||
import { Action, IActionViewItem, IAction } from 'vs/base/common/actions';
|
||||
import { isStringArray } from 'vs/base/common/types';
|
||||
import { IRemoteExplorerService } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { IRemoteExplorerService, MakeAddress } from 'vs/workbench/services/remote/common/remoteExplorerService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { TunnelPanelDescriptor, TunnelViewModel, forwardedPortsViewEnabled } from 'vs/workbench/contrib/remote/browser/tunnelView';
|
||||
import { TunnelPanelDescriptor, TunnelViewModel, forwardedPortsViewEnabled, OpenPortInBrowserAction } from 'vs/workbench/contrib/remote/browser/tunnelView';
|
||||
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeRenderer, ITreeNode, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||
|
@ -56,6 +56,8 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
|||
import { RemoteStatusIndicator } from 'vs/workbench/contrib/remote/browser/remoteIndicator';
|
||||
import { inQuickPickContextKeyValue } from 'vs/workbench/browser/quickaccess';
|
||||
import { Codicon, registerIcon } from 'vs/base/common/codicons';
|
||||
import { INotificationService, IPromptChoice } from 'vs/platform/notification/common/notification';
|
||||
import { UrlFinder } from 'vs/workbench/contrib/remote/browser/urlFinder';
|
||||
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
|
||||
export interface HelpInformation {
|
||||
|
@ -485,8 +487,7 @@ export class RemoteViewPaneContainer extends FilterViewPaneContainer implements
|
|||
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
|
||||
@ITerminalService private readonly terminalService: ITerminalService
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService
|
||||
) {
|
||||
super(VIEWLET_ID, remoteExplorerService.onDidChangeTargetType, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService, viewDescriptorService);
|
||||
this.addConstantViewDescriptors([this.helpPanelDescriptor]);
|
||||
|
@ -561,7 +562,7 @@ export class RemoteViewPaneContainer extends FilterViewPaneContainer implements
|
|||
// This context key is set to false in the constructor, but is expected to be changed by resolver extensions to enable the forwarded ports view.
|
||||
const viewEnabled: boolean = !!forwardedPortsViewEnabled.getValue(this.contextKeyService);
|
||||
if (this.environmentService.configuration.remoteAuthority && !this.tunnelPanelDescriptor && viewEnabled) {
|
||||
this.tunnelPanelDescriptor = new TunnelPanelDescriptor(new TunnelViewModel(this.remoteExplorerService, this.terminalService), this.environmentService);
|
||||
this.tunnelPanelDescriptor = new TunnelPanelDescriptor(new TunnelViewModel(this.remoteExplorerService), this.environmentService);
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([this.tunnelPanelDescriptor!], this.viewContainer);
|
||||
}
|
||||
|
@ -840,6 +841,37 @@ class RemoteAgentConnectionStatusListener implements IWorkbenchContribution {
|
|||
}
|
||||
}
|
||||
|
||||
class AutomaticPortForwarding extends Disposable implements IWorkbenchContribution {
|
||||
constructor(
|
||||
@ITerminalService readonly terminalService: ITerminalService,
|
||||
@INotificationService readonly notificationService: INotificationService,
|
||||
@IOpenerService readonly openerService: IOpenerService,
|
||||
@IViewsService readonly viewsService: IViewsService,
|
||||
@IRemoteExplorerService readonly remoteExplorerService: IRemoteExplorerService
|
||||
) {
|
||||
super();
|
||||
const urlFinder = this._register(new UrlFinder(terminalService));
|
||||
this._register(urlFinder.onDidMatchLocalUrl(async (localUrl) => {
|
||||
const forwarded = await this.remoteExplorerService.forward(localUrl);
|
||||
if (forwarded) {
|
||||
const address = MakeAddress(forwarded.tunnelRemoteHost, forwarded.tunnelRemotePort);
|
||||
const message = nls.localize('remote.tunnelsView.automaticForward', "{0} has been forwarded to {1} locally.",
|
||||
address, forwarded.localAddress);
|
||||
const browserChoice: IPromptChoice = {
|
||||
label: OpenPortInBrowserAction.LABEL,
|
||||
run: () => OpenPortInBrowserAction.run(this.remoteExplorerService.tunnelModel, openerService, address)
|
||||
};
|
||||
const showChoice: IPromptChoice = {
|
||||
label: nls.localize('remote.tunnelsView.showView', "Show Tunnels View"),
|
||||
run: () => viewsService.openViewContainer(VIEWLET_ID)
|
||||
};
|
||||
notificationService.prompt(Severity.Info, message, [browserChoice, showChoice]);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteAgentConnectionStatusListener, LifecyclePhase.Eventually);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteStatusIndicator, LifecyclePhase.Starting);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(AutomaticPortForwarding, LifecyclePhase.Eventually);
|
||||
|
|
|
@ -42,8 +42,6 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
|||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ActionViewItem } from 'vs/base/browser/ui/actionbar/actionViewItems';
|
||||
import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
|
||||
import { UrlFinder } from 'vs/workbench/contrib/remote/browser/urlFinder';
|
||||
|
||||
export const forwardedPortsViewEnabled = new RawContextKey<boolean>('forwardedPortsViewEnabled', false);
|
||||
|
||||
|
@ -74,8 +72,7 @@ export class TunnelViewModel extends Disposable implements ITunnelViewModel {
|
|||
private _candidates: Map<string, { host: string, port: number, detail: string }> = new Map();
|
||||
|
||||
constructor(
|
||||
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService,
|
||||
@ITerminalService readonly terminalService: ITerminalService) {
|
||||
@IRemoteExplorerService private readonly remoteExplorerService: IRemoteExplorerService) {
|
||||
super();
|
||||
this.model = remoteExplorerService.tunnelModel;
|
||||
this._register(this.model.onForwardPort(() => this._onForwardedPortsChanged.fire()));
|
||||
|
@ -89,11 +86,6 @@ export class TunnelViewModel extends Disposable implements ITunnelViewModel {
|
|||
remotePort: 0,
|
||||
description: ''
|
||||
};
|
||||
|
||||
const urlFinder = this._register(new UrlFinder(terminalService));
|
||||
this._register(urlFinder.onDidMatchLocalUrl(localUrl => {
|
||||
this.model.forward(localUrl);
|
||||
}));
|
||||
}
|
||||
|
||||
async groups(): Promise<ITunnelGroup[]> {
|
||||
|
@ -866,7 +858,7 @@ namespace ClosePortAction {
|
|||
}
|
||||
}
|
||||
|
||||
namespace OpenPortInBrowserAction {
|
||||
export namespace OpenPortInBrowserAction {
|
||||
export const ID = 'remote.tunnel.open';
|
||||
export const LABEL = nls.localize('remote.tunnel.open', "Open in Browser");
|
||||
|
||||
|
@ -876,15 +868,19 @@ namespace OpenPortInBrowserAction {
|
|||
const model = accessor.get(IRemoteExplorerService).tunnelModel;
|
||||
const openerService = accessor.get(IOpenerService);
|
||||
const key = MakeAddress(arg.remoteHost, arg.remotePort);
|
||||
const tunnel = model.forwarded.get(key) || model.detected.get(key);
|
||||
let address: string | undefined;
|
||||
if (tunnel && tunnel.localAddress && (address = model.address(tunnel.remoteHost, tunnel.remotePort))) {
|
||||
return openerService.open(URI.parse('http://' + address));
|
||||
}
|
||||
return Promise.resolve();
|
||||
return run(model, openerService, key);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function run(model: TunnelModel, openerService: IOpenerService, key: string) {
|
||||
const tunnel = model.forwarded.get(key) || model.detected.get(key);
|
||||
let address: string | undefined;
|
||||
if (tunnel && tunnel.localAddress && (address = model.address(tunnel.remoteHost, tunnel.remotePort))) {
|
||||
return openerService.open(URI.parse('http://' + address));
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
namespace CopyAddressAction {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue