Merge from vscode 817eb6b0c720a4ecbc13c020afbbebfed667aa09 (#7356)

This commit is contained in:
Anthony Dresser
2019-09-24 21:36:17 -07:00
committed by GitHub
parent a29ae4d3b9
commit 6a6048d40f
541 changed files with 7045 additions and 7287 deletions

View File

@@ -5,7 +5,7 @@
@font-face {
font-family: "codicon";
src: url("./codicon.ttf?e042d2dda15ef7b36b910e3edf539f26") format("truetype");
src: url("./codicon.ttf?3b584136fb1f0186a1ee578cdcb5240b") format("truetype");
}
.codicon[class*='codicon-'] {
@@ -203,152 +203,153 @@
.codicon-folder-active:before { content: "\f162" }
.codicon-folder-opened:before { content: "\f163" }
.codicon-folder:before { content: "\f164" }
.codicon-gift:before { content: "\f165" }
.codicon-gist-secret:before { content: "\f166" }
.codicon-gist:before { content: "\f167" }
.codicon-git-commit:before { content: "\f168" }
.codicon-git-compare:before { content: "\f169" }
.codicon-git-merge:before { content: "\f16a" }
.codicon-github-action:before { content: "\f16b" }
.codicon-github-alt:before { content: "\f16c" }
.codicon-github:before { content: "\f16d" }
.codicon-globe:before { content: "\f16e" }
.codicon-go-to-file:before { content: "\f16f" }
.codicon-grabber:before { content: "\f170" }
.codicon-graph:before { content: "\f171" }
.codicon-gripper:before { content: "\f172" }
.codicon-heart:before { content: "\f173" }
.codicon-history:before { content: "\f174" }
.codicon-home:before { content: "\f175" }
.codicon-horizontal-rule:before { content: "\f176" }
.codicon-hubot:before { content: "\f177" }
.codicon-inbox:before { content: "\f178" }
.codicon-interface:before { content: "\f179" }
.codicon-issue-closed:before { content: "\f17a" }
.codicon-issue-reopened:before { content: "\f17b" }
.codicon-issues:before { content: "\f17c" }
.codicon-italic:before { content: "\f17d" }
.codicon-jersey:before { content: "\f17e" }
.codicon-json:before { content: "\f17f" }
.codicon-kebab-vertical:before { content: "\f180" }
.codicon-key:before { content: "\f181" }
.codicon-keyword:before { content: "\f182" }
.codicon-law:before { content: "\f183" }
.codicon-lightbulb-autofix:before { content: "\f184" }
.codicon-link-external:before { content: "\f185" }
.codicon-link:before { content: "\f186" }
.codicon-list-ordered:before { content: "\f187" }
.codicon-list-unordered:before { content: "\f188" }
.codicon-live-share:before { content: "\f189" }
.codicon-loading:before { content: "\f18a" }
.codicon-location:before { content: "\f18b" }
.codicon-mail-read:before { content: "\f18c" }
.codicon-mail:before { content: "\f18d" }
.codicon-markdown:before { content: "\f18e" }
.codicon-megaphone:before { content: "\f18f" }
.codicon-mention:before { content: "\f190" }
.codicon-method:before { content: "\f191" }
.codicon-milestone:before { content: "\f192" }
.codicon-misc:before { content: "\f193" }
.codicon-mortar-board:before { content: "\f194" }
.codicon-move:before { content: "\f195" }
.codicon-multiple-windows:before { content: "\f196" }
.codicon-mute:before { content: "\f197" }
.codicon-namespace:before { content: "\f198" }
.codicon-no-newline:before { content: "\f199" }
.codicon-note:before { content: "\f19a" }
.codicon-numeric:before { content: "\f19b" }
.codicon-octoface:before { content: "\f19c" }
.codicon-open-preview:before { content: "\f19d" }
.codicon-operator:before { content: "\f19e" }
.codicon-package:before { content: "\f19f" }
.codicon-paintcan:before { content: "\f1a0" }
.codicon-parameter:before { content: "\f1a1" }
.codicon-pause:before { content: "\f1a2" }
.codicon-pin:before { content: "\f1a3" }
.codicon-play:before { content: "\f1a4" }
.codicon-plug:before { content: "\f1a5" }
.codicon-preserve-case:before { content: "\f1a6" }
.codicon-preview:before { content: "\f1a7" }
.codicon-project:before { content: "\f1a8" }
.codicon-property:before { content: "\f1a9" }
.codicon-pulse:before { content: "\f1aa" }
.codicon-question:before { content: "\f1ab" }
.codicon-quote:before { content: "\f1ac" }
.codicon-radio-tower:before { content: "\f1ad" }
.codicon-reactions:before { content: "\f1ae" }
.codicon-references:before { content: "\f1af" }
.codicon-refresh:before { content: "\f1b0" }
.codicon-regex:before { content: "\f1b1" }
.codicon-remote:before { content: "\f1b2" }
.codicon-remove:before { content: "\f1b3" }
.codicon-replace-all:before { content: "\f1b4" }
.codicon-replace:before { content: "\f1b5" }
.codicon-repo-clone:before { content: "\f1b6" }
.codicon-repo-force-push:before { content: "\f1b7" }
.codicon-repo-pull:before { content: "\f1b8" }
.codicon-repo-push:before { content: "\f1b9" }
.codicon-report:before { content: "\f1ba" }
.codicon-request-changes:before { content: "\f1bb" }
.codicon-restart:before { content: "\f1bc" }
.codicon-rocket:before { content: "\f1bd" }
.codicon-root-folder-opened:before { content: "\f1be" }
.codicon-root-folder:before { content: "\f1bf" }
.codicon-rss:before { content: "\f1c0" }
.codicon-ruby:before { content: "\f1c1" }
.codicon-ruler:before { content: "\f1c2" }
.codicon-save-all:before { content: "\f1c3" }
.codicon-save-as:before { content: "\f1c4" }
.codicon-save:before { content: "\f1c5" }
.codicon-screen-full:before { content: "\f1c6" }
.codicon-screen-normal:before { content: "\f1c7" }
.codicon-search-stop:before { content: "\f1c8" }
.codicon-selection:before { content: "\f1c9" }
.codicon-server:before { content: "\f1ca" }
.codicon-settings:before { content: "\f1cb" }
.codicon-shield:before { content: "\f1cc" }
.codicon-smiley:before { content: "\f1cd" }
.codicon-snippet:before { content: "\f1ce" }
.codicon-sort-precedence:before { content: "\f1cf" }
.codicon-split-horizontal:before { content: "\f1d0" }
.codicon-split-vertical:before { content: "\f1d1" }
.codicon-squirrel:before { content: "\f1d2" }
.codicon-star-empty:before { content: "\f1d3" }
.codicon-star-full:before { content: "\f1d4" }
.codicon-star-half:before { content: "\f1d5" }
.codicon-start:before { content: "\f1d6" }
.codicon-step-into:before { content: "\f1d7" }
.codicon-step-out:before { content: "\f1d8" }
.codicon-step-over:before { content: "\f1d9" }
.codicon-string:before { content: "\f1da" }
.codicon-structure:before { content: "\f1db" }
.codicon-tasklist:before { content: "\f1dc" }
.codicon-telescope:before { content: "\f1dd" }
.codicon-text-size:before { content: "\f1de" }
.codicon-three-bars:before { content: "\f1df" }
.codicon-thumbsdown:before { content: "\f1e0" }
.codicon-thumbsup:before { content: "\f1e1" }
.codicon-tools:before { content: "\f1e2" }
.codicon-trash:before { content: "\f1e3" }
.codicon-triangle-down:before { content: "\f1e4" }
.codicon-triangle-left:before { content: "\f1e5" }
.codicon-triangle-right:before { content: "\f1e6" }
.codicon-triangle-up:before { content: "\f1e7" }
.codicon-twitter:before { content: "\f1e8" }
.codicon-unfold:before { content: "\f1e9" }
.codicon-unlock:before { content: "\f1ea" }
.codicon-unmute:before { content: "\f1eb" }
.codicon-unverified:before { content: "\f1ec" }
.codicon-variable:before { content: "\f1ed" }
.codicon-verified:before { content: "\f1ee" }
.codicon-versions:before { content: "\f1ef" }
.codicon-vm-active:before { content: "\f1f0" }
.codicon-vm-outline:before { content: "\f1f1" }
.codicon-vm-running:before { content: "\f1f2" }
.codicon-watch:before { content: "\f1f3" }
.codicon-whitespace:before { content: "\f1f4" }
.codicon-whole-word:before { content: "\f1f5" }
.codicon-window:before { content: "\f1f6" }
.codicon-word-wrap:before { content: "\f1f7" }
.codicon-zoom-in:before { content: "\f1f8" }
.codicon-zoom-out:before { content: "\f1f9" }
.codicon-gear:before { content: "\f165" }
.codicon-gift:before { content: "\f166" }
.codicon-gist-secret:before { content: "\f167" }
.codicon-gist:before { content: "\f168" }
.codicon-git-commit:before { content: "\f169" }
.codicon-git-compare:before { content: "\f16a" }
.codicon-git-merge:before { content: "\f16b" }
.codicon-github-action:before { content: "\f16c" }
.codicon-github-alt:before { content: "\f16d" }
.codicon-github:before { content: "\f16e" }
.codicon-globe:before { content: "\f16f" }
.codicon-go-to-file:before { content: "\f170" }
.codicon-grabber:before { content: "\f171" }
.codicon-graph:before { content: "\f172" }
.codicon-gripper:before { content: "\f173" }
.codicon-heart:before { content: "\f174" }
.codicon-history:before { content: "\f175" }
.codicon-home:before { content: "\f176" }
.codicon-horizontal-rule:before { content: "\f177" }
.codicon-hubot:before { content: "\f178" }
.codicon-inbox:before { content: "\f179" }
.codicon-interface:before { content: "\f17a" }
.codicon-issue-closed:before { content: "\f17b" }
.codicon-issue-reopened:before { content: "\f17c" }
.codicon-issues:before { content: "\f17d" }
.codicon-italic:before { content: "\f17e" }
.codicon-jersey:before { content: "\f17f" }
.codicon-json:before { content: "\f180" }
.codicon-kebab-vertical:before { content: "\f181" }
.codicon-key:before { content: "\f182" }
.codicon-keyword:before { content: "\f183" }
.codicon-law:before { content: "\f184" }
.codicon-lightbulb-autofix:before { content: "\f185" }
.codicon-link-external:before { content: "\f186" }
.codicon-link:before { content: "\f187" }
.codicon-list-ordered:before { content: "\f188" }
.codicon-list-unordered:before { content: "\f189" }
.codicon-live-share:before { content: "\f18a" }
.codicon-loading:before { content: "\f18b" }
.codicon-location:before { content: "\f18c" }
.codicon-mail-read:before { content: "\f18d" }
.codicon-mail:before { content: "\f18e" }
.codicon-markdown:before { content: "\f18f" }
.codicon-megaphone:before { content: "\f190" }
.codicon-mention:before { content: "\f191" }
.codicon-method:before { content: "\f192" }
.codicon-milestone:before { content: "\f193" }
.codicon-misc:before { content: "\f194" }
.codicon-mortar-board:before { content: "\f195" }
.codicon-move:before { content: "\f196" }
.codicon-multiple-windows:before { content: "\f197" }
.codicon-mute:before { content: "\f198" }
.codicon-namespace:before { content: "\f199" }
.codicon-no-newline:before { content: "\f19a" }
.codicon-note:before { content: "\f19b" }
.codicon-numeric:before { content: "\f19c" }
.codicon-octoface:before { content: "\f19d" }
.codicon-open-preview:before { content: "\f19e" }
.codicon-operator:before { content: "\f19f" }
.codicon-package:before { content: "\f1a0" }
.codicon-paintcan:before { content: "\f1a1" }
.codicon-parameter:before { content: "\f1a2" }
.codicon-pause:before { content: "\f1a3" }
.codicon-pin:before { content: "\f1a4" }
.codicon-play:before { content: "\f1a5" }
.codicon-plug:before { content: "\f1a6" }
.codicon-preserve-case:before { content: "\f1a7" }
.codicon-preview:before { content: "\f1a8" }
.codicon-project:before { content: "\f1a9" }
.codicon-property:before { content: "\f1aa" }
.codicon-pulse:before { content: "\f1ab" }
.codicon-question:before { content: "\f1ac" }
.codicon-quote:before { content: "\f1ad" }
.codicon-radio-tower:before { content: "\f1ae" }
.codicon-reactions:before { content: "\f1af" }
.codicon-references:before { content: "\f1b0" }
.codicon-refresh:before { content: "\f1b1" }
.codicon-regex:before { content: "\f1b2" }
.codicon-remote:before { content: "\f1b3" }
.codicon-remove:before { content: "\f1b4" }
.codicon-replace-all:before { content: "\f1b5" }
.codicon-replace:before { content: "\f1b6" }
.codicon-repo-clone:before { content: "\f1b7" }
.codicon-repo-force-push:before { content: "\f1b8" }
.codicon-repo-pull:before { content: "\f1b9" }
.codicon-repo-push:before { content: "\f1ba" }
.codicon-report:before { content: "\f1bb" }
.codicon-request-changes:before { content: "\f1bc" }
.codicon-restart:before { content: "\f1bd" }
.codicon-rocket:before { content: "\f1be" }
.codicon-root-folder-opened:before { content: "\f1bf" }
.codicon-root-folder:before { content: "\f1c0" }
.codicon-rss:before { content: "\f1c1" }
.codicon-ruby:before { content: "\f1c2" }
.codicon-ruler:before { content: "\f1c3" }
.codicon-save-all:before { content: "\f1c4" }
.codicon-save-as:before { content: "\f1c5" }
.codicon-save:before { content: "\f1c6" }
.codicon-screen-full:before { content: "\f1c7" }
.codicon-screen-normal:before { content: "\f1c8" }
.codicon-search-stop:before { content: "\f1c9" }
.codicon-selection:before { content: "\f1ca" }
.codicon-server:before { content: "\f1cb" }
.codicon-settings:before { content: "\f1cc" }
.codicon-shield:before { content: "\f1cd" }
.codicon-smiley:before { content: "\f1ce" }
.codicon-snippet:before { content: "\f1cf" }
.codicon-sort-precedence:before { content: "\f1d0" }
.codicon-split-horizontal:before { content: "\f1d1" }
.codicon-split-vertical:before { content: "\f1d2" }
.codicon-squirrel:before { content: "\f1d3" }
.codicon-star-empty:before { content: "\f1d4" }
.codicon-star-full:before { content: "\f1d5" }
.codicon-star-half:before { content: "\f1d6" }
.codicon-start:before { content: "\f1d7" }
.codicon-step-into:before { content: "\f1d8" }
.codicon-step-out:before { content: "\f1d9" }
.codicon-step-over:before { content: "\f1da" }
.codicon-string:before { content: "\f1db" }
.codicon-structure:before { content: "\f1dc" }
.codicon-tasklist:before { content: "\f1dd" }
.codicon-telescope:before { content: "\f1de" }
.codicon-text-size:before { content: "\f1df" }
.codicon-three-bars:before { content: "\f1e0" }
.codicon-thumbsdown:before { content: "\f1e1" }
.codicon-thumbsup:before { content: "\f1e2" }
.codicon-tools:before { content: "\f1e3" }
.codicon-trash:before { content: "\f1e4" }
.codicon-triangle-down:before { content: "\f1e5" }
.codicon-triangle-left:before { content: "\f1e6" }
.codicon-triangle-right:before { content: "\f1e7" }
.codicon-triangle-up:before { content: "\f1e8" }
.codicon-twitter:before { content: "\f1e9" }
.codicon-unfold:before { content: "\f1ea" }
.codicon-unlock:before { content: "\f1eb" }
.codicon-unmute:before { content: "\f1ec" }
.codicon-unverified:before { content: "\f1ed" }
.codicon-variable:before { content: "\f1ee" }
.codicon-verified:before { content: "\f1ef" }
.codicon-versions:before { content: "\f1f0" }
.codicon-vm-active:before { content: "\f1f1" }
.codicon-vm-outline:before { content: "\f1f2" }
.codicon-vm-running:before { content: "\f1f3" }
.codicon-watch:before { content: "\f1f4" }
.codicon-whitespace:before { content: "\f1f5" }
.codicon-whole-word:before { content: "\f1f6" }
.codicon-window:before { content: "\f1f7" }
.codicon-word-wrap:before { content: "\f1f8" }
.codicon-zoom-in:before { content: "\f1f9" }
.codicon-zoom-out:before { content: "\f1fa" }

View File

@@ -1,24 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { escape } from 'vs/base/common/strings';
export function renderCodicons(text: string): string {
return escape(text);
}
export class CodiconLabel {
private _container: HTMLElement;
constructor(container: HTMLElement) {
this._container = container;
}
set text(text: string) {
this._container.innerHTML = renderCodicons(text || '');
}
}

View File

@@ -295,7 +295,7 @@ export class DropdownMenuActionViewItem extends BaseActionViewItem {
render(container: HTMLElement): void {
const labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable | null => {
this.element = append(el, $('a.action-label.icon'));
this.element = append(el, $('a.action-label.codicon'));
if (this.clazz) {
addClasses(this.element, this.clazz);
}

View File

@@ -32,6 +32,7 @@ export interface IReplaceInputOptions extends IReplaceInputStyles {
export interface IReplaceInputStyles extends IInputBoxStyles {
inputActiveOptionBorder?: Color;
inputActiveOptionBackground?: Color;
}
const NLS_DEFAULT_LABEL = nls.localize('defaultLabel', "input");
@@ -44,7 +45,8 @@ export class PreserveCaseCheckbox extends Checkbox {
actionClassName: 'codicon-preserve-case',
title: NLS_PRESERVE_CASE_LABEL + opts.appendTitle,
isChecked: opts.isChecked,
inputActiveOptionBorder: opts.inputActiveOptionBorder
inputActiveOptionBorder: opts.inputActiveOptionBorder,
inputActiveOptionBackground: opts.inputActiveOptionBackground
});
}
}
@@ -60,6 +62,7 @@ export class ReplaceInput extends Widget {
private fixFocusOnOptionClickEnabled = true;
private inputActiveOptionBorder?: Color;
private inputActiveOptionBackground?: Color;
private inputBackground?: Color;
private inputForeground?: Color;
private inputBorder?: Color;
@@ -105,6 +108,7 @@ export class ReplaceInput extends Widget {
this.label = options.label || NLS_DEFAULT_LABEL;
this.inputActiveOptionBorder = options.inputActiveOptionBorder;
this.inputActiveOptionBackground = options.inputActiveOptionBackground;
this.inputBackground = options.inputBackground;
this.inputForeground = options.inputForeground;
this.inputBorder = options.inputBorder;
@@ -181,6 +185,7 @@ export class ReplaceInput extends Widget {
public style(styles: IReplaceInputStyles): void {
this.inputActiveOptionBorder = styles.inputActiveOptionBorder;
this.inputActiveOptionBackground = styles.inputActiveOptionBackground;
this.inputBackground = styles.inputBackground;
this.inputForeground = styles.inputForeground;
this.inputBorder = styles.inputBorder;
@@ -202,6 +207,7 @@ export class ReplaceInput extends Widget {
if (this.domNode) {
const checkBoxStyles: ICheckboxStyles = {
inputActiveOptionBorder: this.inputActiveOptionBorder,
inputActiveOptionBackground: this.inputActiveOptionBackground,
};
this.preserveCase.style(checkBoxStyles);
@@ -281,7 +287,8 @@ export class ReplaceInput extends Widget {
this.preserveCase = this._register(new PreserveCaseCheckbox({
appendTitle: '',
isChecked: false,
inputActiveOptionBorder: this.inputActiveOptionBorder
inputActiveOptionBorder: this.inputActiveOptionBorder,
inputActiveOptionBackground: this.inputActiveOptionBackground,
}));
this._register(this.preserveCase.onChange(viaKeyboard => {
this._onDidOptionChange.fire(viaKeyboard);

View File

@@ -188,12 +188,12 @@ class BranchNode implements ISplitView, IDisposable {
return this.orientation === Orientation.HORIZONTAL ? this.maximumSize : this.maximumOrthogonalSize;
}
private _onDidChange = new Emitter<number | undefined>();
private readonly _onDidChange = new Emitter<number | undefined>();
readonly onDidChange: Event<number | undefined> = this._onDidChange.event;
private childrenChangeDisposable: IDisposable = Disposable.None;
private _onDidSashReset = new Emitter<number[]>();
private readonly _onDidSashReset = new Emitter<number[]>();
readonly onDidSashReset: Event<number[]> = this._onDidSashReset.event;
private splitviewSashResetDisposable: IDisposable = Disposable.None;
private childrenSashResetDisposable: IDisposable = Disposable.None;
@@ -539,7 +539,7 @@ class LeafNode implements ISplitView, IDisposable {
this._onDidSetLinkedNode.fire(undefined);
}
private _onDidSetLinkedNode = new Emitter<number | undefined>();
private readonly _onDidSetLinkedNode = new Emitter<number | undefined>();
private _onDidViewChange: Event<number | undefined>;
readonly onDidChange: Event<number | undefined>;

View File

@@ -79,7 +79,10 @@ export interface IKeyboardNavigationLabelProvider<T> {
* element always match.
*/
getKeyboardNavigationLabel(element: T): { toString(): string | undefined; } | undefined;
mightProducePrintableCharacter?(event: IKeyboardEvent): boolean;
}
export interface IKeyboardNavigationDelegate {
mightProducePrintableCharacter(event: IKeyboardEvent): boolean;
}
export const enum ListDragOverEffect {

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./list';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { range } from 'vs/base/common/arrays';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent } from './list';
import { List, IListStyles, IListOptions } from './listWidget';
@@ -32,7 +32,7 @@ class PagedRenderer<TElement, TTemplateData> implements IListRenderer<number, IT
renderTemplate(container: HTMLElement): ITemplateData<TTemplateData> {
const data = this.renderer.renderTemplate(container);
return { data, disposable: { dispose: () => { } } };
return { data, disposable: Disposable.None };
}
renderElement(index: number, _: number, data: ITemplateData<TTemplateData>, height: number | undefined): void {
@@ -127,7 +127,7 @@ export class PagedList<T> implements IDisposable {
}
get onPin(): Event<IListEvent<T>> {
return Event.map(this.list.onPin, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
return Event.map(this.list.onDidPin, ({ elements, indexes }) => ({ elements: elements.map(e => this._model.get(e)), indexes }));
}
get onContextMenu(): Event<IListContextMenuEvent<T>> {

View File

@@ -190,7 +190,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private readonly disposables: DisposableStore = new DisposableStore();
private _onDidChangeContentHeight = new Emitter<number>();
private readonly _onDidChangeContentHeight = new Emitter<number>();
readonly onDidChangeContentHeight: Event<number> = Event.latch(this._onDidChangeContentHeight.event);
get contentHeight(): number { return this.rangeMap.size; }

View File

@@ -16,7 +16,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { Event, Emitter, EventBufferer } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole, ListError } from './list';
import { IListVirtualDelegate, IListRenderer, IListEvent, IListContextMenuEvent, IListMouseEvent, IListTouchEvent, IListGestureEvent, IIdentityProvider, IKeyboardNavigationLabelProvider, IListDragAndDrop, IListDragOverReaction, ListAriaRootRole, ListError, IKeyboardNavigationDelegate } from './list';
import { ListView, IListViewOptions, IListViewDragAndDrop, IAriaProvider } from './listView';
import { Color } from 'vs/base/common/color';
import { mixin } from 'vs/base/common/objects';
@@ -110,7 +110,7 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
private indexes: number[] = [];
private sortedIndexes: number[] = [];
private _onChange = new Emitter<ITraitChangeEvent>();
private readonly _onChange = new Emitter<ITraitChangeEvent>();
readonly onChange: Event<ITraitChangeEvent> = this._onChange.event;
get trait(): string { return this._trait; }
@@ -176,7 +176,7 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
}
dispose() {
this._onChange = dispose(this._onChange);
dispose(this._onChange);
}
}
@@ -322,16 +322,18 @@ enum TypeLabelControllerState {
Typing
}
export function mightProducePrintableCharacter(event: IKeyboardEvent): boolean {
if (event.ctrlKey || event.metaKey || event.altKey) {
return false;
}
export const DefaultKeyboardNavigationDelegate = new class implements IKeyboardNavigationDelegate {
mightProducePrintableCharacter(event: IKeyboardEvent): boolean {
if (event.ctrlKey || event.metaKey || event.altKey) {
return false;
}
return (event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z)
|| (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9)
|| (event.keyCode >= KeyCode.NUMPAD_0 && event.keyCode <= KeyCode.NUMPAD_9)
|| (event.keyCode >= KeyCode.US_SEMICOLON && event.keyCode <= KeyCode.US_QUOTE);
}
return (event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z)
|| (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9)
|| (event.keyCode >= KeyCode.NUMPAD_0 && event.keyCode <= KeyCode.NUMPAD_9)
|| (event.keyCode >= KeyCode.US_SEMICOLON && event.keyCode <= KeyCode.US_QUOTE);
}
};
class TypeLabelController<T> implements IDisposable {
@@ -347,7 +349,8 @@ class TypeLabelController<T> implements IDisposable {
constructor(
private list: List<T>,
private view: ListView<T>,
private keyboardNavigationLabelProvider: IKeyboardNavigationLabelProvider<T>
private keyboardNavigationLabelProvider: IKeyboardNavigationLabelProvider<T>,
private delegate: IKeyboardNavigationDelegate
) {
this.updateOptions(list.options);
}
@@ -379,7 +382,7 @@ class TypeLabelController<T> implements IDisposable {
.filter(e => !isInputElement(e.target as HTMLElement))
.filter(() => this.automaticKeyboardNavigation || this.triggered)
.map(event => new StandardKeyboardEvent(event))
.filter(this.keyboardNavigationLabelProvider.mightProducePrintableCharacter ? e => this.keyboardNavigationLabelProvider.mightProducePrintableCharacter!(e) : e => mightProducePrintableCharacter(e))
.filter(e => this.delegate.mightProducePrintableCharacter(e))
.forEach(e => { e.stopPropagation(); e.preventDefault(); })
.map(event => event.browserEvent.key)
.event;
@@ -818,6 +821,7 @@ export interface IListOptions<T> extends IListStyles {
readonly enableKeyboardNavigation?: boolean;
readonly automaticKeyboardNavigation?: boolean;
readonly keyboardNavigationLabelProvider?: IKeyboardNavigationLabelProvider<T>;
readonly keyboardNavigationDelegate?: IKeyboardNavigationDelegate;
readonly ariaRole?: ListAriaRootRole;
readonly ariaLabel?: string;
readonly keyboardSupport?: boolean;
@@ -1107,13 +1111,11 @@ export class List<T> implements ISpliceable<T>, IDisposable {
return Event.map(this.eventBufferer.wrapEvent(this.selection.onChange), e => this.toListEvent(e));
}
private _onDidOpen = new Emitter<IListEvent<T>>();
private readonly _onDidOpen = new Emitter<IListEvent<T>>();
readonly onDidOpen: Event<IListEvent<T>> = this._onDidOpen.event;
private _onPin = new Emitter<number[]>();
@memoize get onPin(): Event<IListEvent<T>> {
return Event.map(this._onPin.event, indexes => this.toListEvent({ indexes }));
}
private readonly _onDidPin = new Emitter<IListEvent<T>>();
readonly onDidPin: Event<IListEvent<T>> = this._onDidPin.event;
get domId(): string { return this.view.domId; }
get onDidScroll(): Event<ScrollEvent> { return this.view.onDidScroll; }
@@ -1166,7 +1168,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
readonly onDidFocus: Event<void>;
readonly onDidBlur: Event<void>;
private _onDidDispose = new Emitter<void>();
private readonly _onDidDispose = new Emitter<void>();
readonly onDidDispose: Event<void> = this._onDidDispose.event;
constructor(
@@ -1228,7 +1230,8 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
if (_options.keyboardNavigationLabelProvider) {
this.typeLabelController = new TypeLabelController(this, this.view, _options.keyboardNavigationLabelProvider);
const delegate = _options.keyboardNavigationDelegate || DefaultKeyboardNavigationDelegate;
this.typeLabelController = new TypeLabelController(this, this.view, _options.keyboardNavigationLabelProvider, delegate);
this.disposables.add(this.typeLabelController);
}
@@ -1582,14 +1585,14 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this._onDidOpen.fire({ indexes, elements: indexes.map(i => this.view.element(i)), browserEvent });
}
pin(indexes: number[]): void {
pin(indexes: number[], browserEvent?: UIEvent): void {
for (const index of indexes) {
if (index < 0 || index >= this.length) {
throw new ListError(this.user, `Invalid index ${index}`);
}
}
this._onPin.fire(indexes);
this._onDidPin.fire({ indexes, elements: indexes.map(i => this.view.element(i)), browserEvent });
}
style(styles: IListStyles): void {
@@ -1626,7 +1629,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.disposables.dispose();
this._onDidOpen.dispose();
this._onPin.dispose();
this._onDidPin.dispose();
this._onDidDispose.dispose();
}
}

View File

@@ -39,8 +39,6 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
get templateId(): string { return SELECT_OPTION_ENTRY_TEMPLATE_ID; }
constructor() { }
renderTemplate(container: HTMLElement): ISelectListTemplateData {
const data: ISelectListTemplateData = Object.create(null);
data.disposables = [];

View File

@@ -76,6 +76,9 @@
background-position: center center;
background-repeat: no-repeat;
margin-right: 0;
display: flex;
align-items: center;
justify-content: center;
}
/* Bold font style does not go well with CJK fonts */

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 8C4 8.19778 3.94135 8.39112 3.83147 8.55557C3.72159 8.72002 3.56541 8.84819 3.38268 8.92388C3.19996 8.99957 2.99889 9.01937 2.80491 8.98079C2.61093 8.9422 2.43275 8.84696 2.29289 8.70711C2.15304 8.56725 2.0578 8.38907 2.01922 8.19509C1.98063 8.00111 2.00043 7.80004 2.07612 7.61732C2.15181 7.43459 2.27998 7.27841 2.44443 7.16853C2.60888 7.05865 2.80222 7 3 7C3.26522 7 3.51957 7.10536 3.70711 7.29289C3.89464 7.48043 4 7.73478 4 8Z" fill="#C5C5C5"/>
<path d="M9 8C9 8.19778 8.94135 8.39112 8.83147 8.55557C8.72159 8.72002 8.56541 8.84819 8.38268 8.92388C8.19996 8.99957 7.99889 9.01937 7.80491 8.98079C7.61093 8.9422 7.43275 8.84696 7.29289 8.70711C7.15304 8.56725 7.0578 8.38907 7.01922 8.19509C6.98063 8.00111 7.00043 7.80004 7.07612 7.61732C7.15181 7.43459 7.27998 7.27841 7.44443 7.16853C7.60888 7.05865 7.80222 7 8 7C8.26522 7 8.51957 7.10536 8.70711 7.29289C8.89464 7.48043 9 7.73478 9 8Z" fill="#C5C5C5"/>
<path d="M14 8C14 8.19778 13.9414 8.39112 13.8315 8.55557C13.7216 8.72002 13.5654 8.84819 13.3827 8.92388C13.2 8.99957 12.9989 9.01937 12.8049 8.98079C12.6109 8.9422 12.4327 8.84696 12.2929 8.70711C12.153 8.56725 12.0578 8.38907 12.0192 8.19509C11.9806 8.00111 12.0004 7.80004 12.0761 7.61732C12.1518 7.43459 12.28 7.27841 12.4444 7.16853C12.6089 7.05865 12.8022 7 13 7C13.2652 7 13.5196 7.10536 13.7071 7.29289C13.8946 7.48043 14 7.73478 14 8Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 8C4 8.19778 3.94135 8.39112 3.83147 8.55557C3.72159 8.72002 3.56541 8.84819 3.38268 8.92388C3.19996 8.99957 2.99889 9.01937 2.80491 8.98079C2.61093 8.9422 2.43275 8.84696 2.29289 8.70711C2.15304 8.56725 2.0578 8.38907 2.01922 8.19509C1.98063 8.00111 2.00043 7.80004 2.07612 7.61732C2.15181 7.43459 2.27998 7.27841 2.44443 7.16853C2.60888 7.05865 2.80222 7 3 7C3.26522 7 3.51957 7.10536 3.70711 7.29289C3.89464 7.48043 4 7.73478 4 8Z" fill="white"/>
<path d="M9 8C9 8.19778 8.94135 8.39112 8.83147 8.55557C8.72159 8.72002 8.56541 8.84819 8.38268 8.92388C8.19996 8.99957 7.99889 9.01937 7.80491 8.98079C7.61093 8.9422 7.43275 8.84696 7.29289 8.70711C7.15304 8.56725 7.0578 8.38907 7.01922 8.19509C6.98063 8.00111 7.00043 7.80004 7.07612 7.61732C7.15181 7.43459 7.27998 7.27841 7.44443 7.16853C7.60888 7.05865 7.80222 7 8 7C8.26522 7 8.51957 7.10536 8.70711 7.29289C8.89464 7.48043 9 7.73478 9 8Z" fill="white"/>
<path d="M14 8C14 8.19778 13.9414 8.39112 13.8315 8.55557C13.7216 8.72002 13.5654 8.84819 13.3827 8.92388C13.2 8.99957 12.9989 9.01937 12.8049 8.98079C12.6109 8.9422 12.4327 8.84696 12.2929 8.70711C12.153 8.56725 12.0578 8.38907 12.0192 8.19509C11.9806 8.00111 12.0004 7.80004 12.0761 7.61732C12.1518 7.43459 12.28 7.27841 12.4444 7.16853C12.6089 7.05865 12.8022 7 13 7C13.2652 7 13.5196 7.10536 13.7071 7.29289C13.8946 7.48043 14 7.73478 14 8Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,5 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4 8C4 8.19778 3.94135 8.39112 3.83147 8.55557C3.72159 8.72002 3.56541 8.84819 3.38268 8.92388C3.19996 8.99957 2.99889 9.01937 2.80491 8.98079C2.61093 8.9422 2.43275 8.84696 2.29289 8.70711C2.15304 8.56725 2.0578 8.38907 2.01922 8.19509C1.98063 8.00111 2.00043 7.80004 2.07612 7.61732C2.15181 7.43459 2.27998 7.27841 2.44443 7.16853C2.60888 7.05865 2.80222 7 3 7C3.26522 7 3.51957 7.10536 3.70711 7.29289C3.89464 7.48043 4 7.73478 4 8Z" fill="#424242"/>
<path d="M9 8C9 8.19778 8.94135 8.39112 8.83147 8.55557C8.72159 8.72002 8.56541 8.84819 8.38268 8.92388C8.19996 8.99957 7.99889 9.01937 7.80491 8.98079C7.61093 8.9422 7.43275 8.84696 7.29289 8.70711C7.15304 8.56725 7.0578 8.38907 7.01922 8.19509C6.98063 8.00111 7.00043 7.80004 7.07612 7.61732C7.15181 7.43459 7.27998 7.27841 7.44443 7.16853C7.60888 7.05865 7.80222 7 8 7C8.26522 7 8.51957 7.10536 8.70711 7.29289C8.89464 7.48043 9 7.73478 9 8Z" fill="#424242"/>
<path d="M14 8C14 8.19778 13.9414 8.39112 13.8315 8.55557C13.7216 8.72002 13.5654 8.84819 13.3827 8.92388C13.2 8.99957 12.9989 9.01937 12.8049 8.98079C12.6109 8.9422 12.4327 8.84696 12.2929 8.70711C12.153 8.56725 12.0578 8.38907 12.0192 8.19509C11.9806 8.00111 12.0004 7.80004 12.0761 7.61732C12.1518 7.43459 12.28 7.27841 12.4444 7.16853C12.6089 7.05865 12.8022 7 13 7C13.2652 7 13.5196 7.10536 13.7071 7.29289C13.8946 7.48043 14 7.73478 14 8Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -7,15 +7,3 @@
display: inline-block;
padding: 0;
}
.vs .monaco-toolbar .action-label.toolbar-toggle-more {
background-image: url('ellipsis-light.svg');
}
.vs-dark .monaco-toolbar .action-label.toolbar-toggle-more {
background-image: url('ellipsis-dark.svg');
}
.hc-black .monaco-toolbar .action-label.toolbar-toggle-more {
background-image: url('ellipsis-hc.svg');
}

View File

@@ -65,7 +65,7 @@ export class ToolBar extends Disposable {
this.options.actionViewItemProvider,
this.actionRunner,
this.options.getKeyBinding,
'toolbar-toggle-more',
'codicon-more',
this.options.anchorAlignmentProvider
);
this.toggleMenuActionViewItem.value.setActionContext(this.actionBar.context);

View File

@@ -5,16 +5,16 @@
import 'vs/css!./media/tree';
import { IDisposable, dispose, Disposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { IListOptions, List, IListStyles, mightProducePrintableCharacter, MouseController } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { IListOptions, List, IListStyles, MouseController, DefaultKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListEvent, IListContextMenuEvent, IListDragAndDrop, IListDragOverReaction, IKeyboardNavigationLabelProvider, IIdentityProvider, IKeyboardNavigationDelegate } from 'vs/base/browser/ui/list/list';
import { append, $, toggleClass, getDomNodePagePosition, removeClass, addClass, hasClass, hasParentWithClass, createStyleSheet, clearNode } from 'vs/base/browser/dom';
import { Event, Relay, Emitter, EventBufferer } from 'vs/base/common/event';
import { StandardKeyboardEvent, IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent, TreeMouseEventTarget } from 'vs/base/browser/ui/tree/tree';
import { ISpliceable } from 'vs/base/common/sequence';
import { IDragAndDropData, StaticDND, DragAndDropData } from 'vs/base/browser/dnd';
import { range, equals, distinctES6 } from 'vs/base/common/arrays';
import { range, equals, distinctES6, fromSet } from 'vs/base/common/arrays';
import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView';
import { domEvent } from 'vs/base/browser/event';
import { fuzzyScore, FuzzyScore } from 'vs/base/common/filters';
@@ -567,7 +567,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
private _empty: boolean = false;
get empty(): boolean { return this._empty; }
private _onDidChangeEmptyState = new Emitter<boolean>();
private readonly _onDidChangeEmptyState = new Emitter<boolean>();
readonly onDidChangeEmptyState: Event<boolean> = Event.latch(this._onDidChangeEmptyState.event);
private positionClassName = 'ne';
@@ -581,7 +581,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
private automaticKeyboardNavigation = true;
private triggered = false;
private _onDidChangePattern = new Emitter<string>();
private readonly _onDidChangePattern = new Emitter<string>();
readonly onDidChangePattern = this._onDidChangePattern.event;
private enabledDisposables: IDisposable[] = [];
@@ -592,7 +592,7 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
model: ITreeModel<T, TFilterData, any>,
private view: List<ITreeNode<T, TFilterData>>,
private filter: TypeFilter<T>,
private keyboardNavigationLabelProvider: IKeyboardNavigationLabelProvider<T>
private keyboardNavigationDelegate: IKeyboardNavigationDelegate
) {
this.domNode = $(`.monaco-list-type-filter.${this.positionClassName}`);
this.domNode.draggable = true;
@@ -658,13 +658,12 @@ class TypeFilterController<T, TFilterData> implements IDisposable {
return;
}
const isPrintableCharEvent = this.keyboardNavigationLabelProvider.mightProducePrintableCharacter ? (e: IKeyboardEvent) => this.keyboardNavigationLabelProvider.mightProducePrintableCharacter!(e) : (e: IKeyboardEvent) => mightProducePrintableCharacter(e);
const onKeyDown = Event.chain(domEvent(this.view.getHTMLElement(), 'keydown'))
.filter(e => !isInputElement(e.target as HTMLElement) || e.target === this.filterOnTypeDomNode)
.map(e => new StandardKeyboardEvent(e))
.filter(this.keyboardNavigationEventFilter || (() => true))
.filter(() => this.automaticKeyboardNavigation || this.triggered)
.filter(e => isPrintableCharEvent(e) || ((this.pattern.length > 0 || this.triggered) && ((e.keyCode === KeyCode.Escape || e.keyCode === KeyCode.Backspace) && !e.altKey && !e.ctrlKey && !e.metaKey) || (e.keyCode === KeyCode.Backspace && (isMacintosh ? (e.altKey && !e.metaKey) : e.ctrlKey) && !e.shiftKey)))
.filter(e => this.keyboardNavigationDelegate.mightProducePrintableCharacter(e) || ((this.pattern.length > 0 || this.triggered) && ((e.keyCode === KeyCode.Escape || e.keyCode === KeyCode.Backspace) && !e.altKey && !e.ctrlKey && !e.metaKey) || (e.keyCode === KeyCode.Backspace && (isMacintosh ? (e.altKey && !e.metaKey) : e.ctrlKey) && !e.shiftKey)))
.forEach(e => { e.stopPropagation(); e.preventDefault(); })
.event;
@@ -935,7 +934,7 @@ class Trait<T> {
private nodes: ITreeNode<T, any>[] = [];
private elements: T[] | undefined;
private _onDidChange = new Emitter<ITreeEvent<T>>();
private readonly _onDidChange = new Emitter<ITreeEvent<T>>();
readonly onDidChange = this._onDidChange.event;
private _nodeSet: Set<ITreeNode<T, any>> | undefined;
@@ -1189,6 +1188,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
get onDidChangeFocus(): Event<ITreeEvent<T>> { return this.eventBufferer.wrapEvent(this.focus.onDidChange); }
get onDidChangeSelection(): Event<ITreeEvent<T>> { return this.eventBufferer.wrapEvent(this.selection.onDidChange); }
get onDidOpen(): Event<ITreeEvent<T>> { return Event.map(this.view.onDidOpen, asTreeEvent); }
get onDidPin(): Event<ITreeEvent<T>> { return Event.map(this.view.onDidPin, asTreeEvent); }
get onMouseClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onMouseClick, asTreeMouseEvent); }
get onMouseDblClick(): Event<ITreeMouseEvent<T>> { return Event.map(this.view.onMouseDblClick, asTreeMouseEvent); }
@@ -1204,7 +1204,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
get onDidChangeCollapseState(): Event<ICollapseStateChangeEvent<T, TFilterData>> { return this.model.onDidChangeCollapseState; }
get onDidChangeRenderNodeCount(): Event<ITreeNode<T, TFilterData>> { return this.model.onDidChangeRenderNodeCount; }
private _onWillRefilter = new Emitter<void>();
private readonly _onWillRefilter = new Emitter<void>();
readonly onWillRefilter: Event<void> = this._onWillRefilter.event;
get filterOnType(): boolean { return !!this._options.filterOnType; }
@@ -1213,7 +1213,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
get openOnSingleClick(): boolean { return typeof this._options.openOnSingleClick === 'undefined' ? true : this._options.openOnSingleClick; }
get expandOnlyOnTwistieClick(): boolean | ((e: T) => boolean) { return typeof this._options.expandOnlyOnTwistieClick === 'undefined' ? false : this._options.expandOnlyOnTwistieClick; }
private _onDidUpdateOptions = new Emitter<IAbstractTreeOptions<T, TFilterData>>();
private readonly _onDidUpdateOptions = new Emitter<IAbstractTreeOptions<T, TFilterData>>();
readonly onDidUpdateOptions: Event<IAbstractTreeOptions<T, TFilterData>> = this._onDidUpdateOptions.event;
get onDidDispose(): Event<void> { return this.view.onDidDispose; }
@@ -1228,7 +1228,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
const treeDelegate = new ComposedTreeDelegate<T, ITreeNode<T, TFilterData>>(delegate);
const onDidChangeCollapseStateRelay = new Relay<ICollapseStateChangeEvent<T, TFilterData>>();
const onDidChangeActiveNodes = new Relay<ITreeNode<T, TFilterData>[]>();
const onDidChangeActiveNodes = new Emitter<ITreeNode<T, TFilterData>[]>();
const activeNodes = new EventCollection(onDidChangeActiveNodes.event);
this.disposables.push(activeNodes);
@@ -1251,11 +1251,23 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
onDidChangeCollapseStateRelay.input = this.model.onDidChangeCollapseState;
this.model.onDidSplice(e => {
this.focus.onDidModelSplice(e);
this.selection.onDidModelSplice(e);
}, null, this.disposables);
this.eventBufferer.bufferEvents(() => {
this.focus.onDidModelSplice(e);
this.selection.onDidModelSplice(e);
});
onDidChangeActiveNodes.input = Event.map(Event.any<any>(this.focus.onDidChange, this.selection.onDidChange, this.model.onDidSplice), () => [...this.focus.getNodes(), ...this.selection.getNodes()]);
const set = new Set<ITreeNode<T, TFilterData>>();
for (const node of this.focus.getNodes()) {
set.add(node);
}
for (const node of this.selection.getNodes()) {
set.add(node);
}
onDidChangeActiveNodes.fire(fromSet(set));
}, null, this.disposables);
if (_options.keyboardSupport !== false) {
const onKeyDown = Event.chain(this.view.onKeyDown)
@@ -1268,7 +1280,8 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
}
if (_options.keyboardNavigationLabelProvider) {
this.typeFilterController = new TypeFilterController(this, this.model, this.view, filter!, _options.keyboardNavigationLabelProvider);
const delegate = _options.keyboardNavigationDelegate || DefaultKeyboardNavigationDelegate;
this.typeFilterController = new TypeFilterController(this, this.model, this.view, filter!, delegate);
this.focusNavigationFilter = node => this.typeFilterController!.shouldAllowFocus(node);
this.disposables.push(this.typeFilterController!);
}

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer } from 'vs/base/browser/ui/tree/objectTree';
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper } from 'vs/base/browser/ui/tree/tree';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
@@ -1010,6 +1010,24 @@ export interface ITreeCompressionDelegate<T> {
isIncompressible(element: T): boolean;
}
function asCompressibleObjectTreeOptions<TInput, T, TFilterData>(options?: ICompressibleAsyncDataTreeOptions<T, TFilterData>): ICompressibleObjectTreeOptions<IAsyncDataTreeNode<TInput, T>, TFilterData> | undefined {
const objectTreeOptions = options && asObjectTreeOptions(options);
return objectTreeOptions && {
...objectTreeOptions,
keyboardNavigationLabelProvider: objectTreeOptions.keyboardNavigationLabelProvider && {
...objectTreeOptions.keyboardNavigationLabelProvider,
getCompressedNodeKeyboardNavigationLabel(els) {
return options!.keyboardNavigationLabelProvider!.getCompressedNodeKeyboardNavigationLabel(els.map(e => e.element as T));
}
}
};
}
export interface ICompressibleAsyncDataTreeOptions<T, TFilterData = void> extends IAsyncDataTreeOptions<T, TFilterData> {
readonly keyboardNavigationLabelProvider?: ICompressibleKeyboardNavigationLabelProvider<T>;
}
export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends AsyncDataTree<TInput, T, TFilterData> {
protected readonly compressibleNodeMapper: CompressibleAsyncDataTreeNodeMapper<TInput, T, TFilterData> = new WeakMapper(node => new CompressibleAsyncDataTreeNodeWrapper(node));
@@ -1031,11 +1049,11 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ICompressibleTreeRenderer<T, TFilterData, any>[],
options: IAsyncDataTreeOptions<T, TFilterData>
options: ICompressibleAsyncDataTreeOptions<T, TFilterData>
): ObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData> {
const objectTreeDelegate = new ComposedTreeDelegate<TInput | T, IAsyncDataTreeNode<TInput, T>>(delegate);
const objectTreeRenderers = renderers.map(r => new CompressibleAsyncDataTreeRenderer(r, this.nodeMapper, () => this.compressibleNodeMapper, this._onDidChangeNodeSlowState.event));
const objectTreeOptions = asObjectTreeOptions<TInput, T, TFilterData>(options) || {};
const objectTreeOptions = asCompressibleObjectTreeOptions<TInput, T, TFilterData>(options) || {};
return new CompressibleObjectTree(user, container, objectTreeDelegate, objectTreeRenderers, objectTreeOptions);
}

View File

@@ -336,7 +336,7 @@ function mapOptions<T, TFilterData>(compressedNodeUnwrapper: CompressedNodeUnwra
...options,
sorter: options.sorter && {
compare(node: ICompressedTreeNode<T>, otherNode: ICompressedTreeNode<T>): number {
return options.sorter!.compare(compressedNodeUnwrapper(node), compressedNodeUnwrapper(otherNode));
return options.sorter!.compare(node.elements[0], otherNode.elements[0]);
}
},
identityProvider: options.identityProvider && {

View File

@@ -162,9 +162,10 @@ export class DataTree<TInput, T, TFilterData = void> extends AbstractTree<T | nu
const children = this.dataSource.getChildren(element);
const elements = Iterator.map<any, ITreeElement<T>>(Iterator.fromArray(children), element => {
const { elements: children, size } = this.iterate(element, isCollapsed);
const collapsible = this.dataSource.hasChildren ? this.dataSource.hasChildren(element) : undefined;
const collapsed = size === 0 ? undefined : (isCollapsed && isCollapsed(element));
return { element, children, collapsed };
return { element, children, collapsible, collapsed };
});
return { elements, size: children.length };

View File

@@ -62,17 +62,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
private root: IIndexTreeNode<T, TFilterData>;
private eventBufferer = new EventBufferer();
private _onDidChangeCollapseState = new Emitter<ICollapseStateChangeEvent<T, TFilterData>>();
private readonly _onDidChangeCollapseState = new Emitter<ICollapseStateChangeEvent<T, TFilterData>>();
readonly onDidChangeCollapseState: Event<ICollapseStateChangeEvent<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeCollapseState.event);
private _onDidChangeRenderNodeCount = new Emitter<ITreeNode<T, TFilterData>>();
private readonly _onDidChangeRenderNodeCount = new Emitter<ITreeNode<T, TFilterData>>();
readonly onDidChangeRenderNodeCount: Event<ITreeNode<T, TFilterData>> = this.eventBufferer.wrapEvent(this._onDidChangeRenderNodeCount.event);
private collapseByDefault: boolean;
private filter?: ITreeFilter<T, TFilterData>;
private autoExpandSingleChildren: boolean;
private _onDidSplice = new Emitter<ITreeModelSpliceEvent<T, TFilterData>>();
private readonly _onDidSplice = new Emitter<ITreeModelSpliceEvent<T, TFilterData>>();
readonly onDidSplice = this._onDidSplice.event;
constructor(
@@ -169,7 +169,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
parentNode.visibleChildrenCount += insertedVisibleChildrenCount - deletedVisibleChildrenCount;
if (revealed && visible) {
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + node.renderNodeCount, 0);
const visibleDeleteCount = deletedNodes.reduce((r, node) => r + (node.visible ? node.renderNodeCount : 0), 0);
this._updateAncestorsRenderNodeCount(parentNode, renderNodeCount - visibleDeleteCount);
this.list.splice(listIndex, visibleDeleteCount, treeListElementsToInsert);

View File

@@ -8,9 +8,10 @@ import { AbstractTree, IAbstractTreeOptions } from 'vs/base/browser/ui/tree/abst
import { ISpliceable } from 'vs/base/common/sequence';
import { ITreeNode, ITreeModel, ITreeElement, ITreeRenderer, ITreeSorter, ICollapseStateChangeEvent } from 'vs/base/browser/ui/tree/tree';
import { ObjectTreeModel, IObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { IListVirtualDelegate, IKeyboardNavigationLabelProvider } from 'vs/base/browser/ui/list/list';
import { Event } from 'vs/base/common/event';
import { CompressibleObjectTreeModel, ElementMapper, ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
import { memoize } from 'vs/base/common/decorators';
export interface IObjectTreeOptions<T, TFilterData = void> extends IAbstractTreeOptions<T, TFilterData> {
sorter?: ITreeSorter<T>;
@@ -77,9 +78,12 @@ class CompressibleRenderer<T, TFilterData, TTemplateData> implements ITreeRender
readonly templateId: string;
readonly onDidChangeTwistieState: Event<T> | undefined;
compressedTreeNodeProvider: ICompressedTreeNodeProvider<T, TFilterData>;
@memoize
private get compressedTreeNodeProvider(): ICompressedTreeNodeProvider<T, TFilterData> {
return this._compressedTreeNodeProvider();
}
constructor(private renderer: ICompressibleTreeRenderer<T, TFilterData, TTemplateData>) {
constructor(private _compressedTreeNodeProvider: () => ICompressedTreeNodeProvider<T, TFilterData>, private renderer: ICompressibleTreeRenderer<T, TFilterData, TTemplateData>) {
this.templateId = renderer.templateId;
if (renderer.onDidChangeTwistieState) {
@@ -127,7 +131,38 @@ class CompressibleRenderer<T, TFilterData, TTemplateData> implements ITreeRender
}
}
export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = void> extends ObjectTree<T, TFilterData> {
export interface ICompressibleKeyboardNavigationLabelProvider<T> extends IKeyboardNavigationLabelProvider<T> {
getCompressedNodeKeyboardNavigationLabel(elements: T[]): { toString(): string | undefined; } | undefined;
}
export interface ICompressibleObjectTreeOptions<T, TFilterData = void> extends IObjectTreeOptions<T, TFilterData> {
readonly keyboardNavigationLabelProvider?: ICompressibleKeyboardNavigationLabelProvider<T>;
}
function asObjectTreeOptions<T, TFilterData>(compressedTreeNodeProvider: () => ICompressedTreeNodeProvider<T, TFilterData>, options?: ICompressibleObjectTreeOptions<T, TFilterData>): IObjectTreeOptions<T, TFilterData> | undefined {
return options && {
...options,
keyboardNavigationLabelProvider: options.keyboardNavigationLabelProvider && {
getKeyboardNavigationLabel(e: T) {
let compressedTreeNode: ITreeNode<ICompressedTreeNode<T>, TFilterData>;
try {
compressedTreeNode = compressedTreeNodeProvider().getCompressedTreeNode(e);
} catch {
return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(e);
}
if (compressedTreeNode.element.elements.length === 1) {
return options.keyboardNavigationLabelProvider!.getKeyboardNavigationLabel(e);
} else {
return options.keyboardNavigationLabelProvider!.getCompressedNodeKeyboardNavigationLabel(compressedTreeNode.element.elements);
}
}
}
};
}
export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = void> extends ObjectTree<T, TFilterData> implements ICompressedTreeNodeProvider<T, TFilterData> {
protected model: CompressibleObjectTreeModel<T, TFilterData>;
@@ -136,11 +171,11 @@ export class CompressibleObjectTree<T extends NonNullable<any>, TFilterData = vo
container: HTMLElement,
delegate: IListVirtualDelegate<T>,
renderers: ICompressibleTreeRenderer<T, TFilterData, any>[],
options: IObjectTreeOptions<T, TFilterData> = {}
options: ICompressibleObjectTreeOptions<T, TFilterData> = {}
) {
const compressibleRenderers = renderers.map(r => new CompressibleRenderer(r));
super(user, container, delegate, compressibleRenderers, options);
compressibleRenderers.forEach(r => r.compressedTreeNodeProvider = this);
const compressedTreeNodeProvider = () => this;
const compressibleRenderers = renderers.map(r => new CompressibleRenderer(compressedTreeNodeProvider, r));
super(user, container, delegate, compressibleRenderers, asObjectTreeOptions(compressedTreeNodeProvider, options));
}
setChildren(element: T | null, children?: ISequence<ICompressedTreeElement<T>>): void {

View File

@@ -9,6 +9,7 @@ import { IndexTreeModel, IIndexTreeModelOptions } from 'vs/base/browser/ui/tree/
import { Event } from 'vs/base/common/event';
import { ITreeModel, ITreeNode, ITreeElement, ITreeSorter, ICollapseStateChangeEvent, ITreeModelSpliceEvent, TreeError } from 'vs/base/browser/ui/tree/tree';
import { IIdentityProvider } from 'vs/base/browser/ui/list/list';
import { mergeSort } from 'vs/base/common/arrays';
export type ITreeNodeCallback<T, TFilterData> = (node: ITreeNode<T, TFilterData>) => void;
@@ -123,7 +124,7 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
let iterator = elements ? getSequenceIterator(elements) : Iterator.empty<ITreeElement<T>>();
if (this.sorter) {
iterator = Iterator.fromArray(Iterator.collect(iterator).sort(this.sorter.compare.bind(this.sorter)));
iterator = Iterator.fromArray(mergeSort(Iterator.collect(iterator), this.sorter.compare.bind(this.sorter)));
}
return Iterator.map(iterator, treeElement => {

View File

@@ -164,6 +164,7 @@ export interface ITreeNavigator<T> {
}
export interface IDataSource<TInput, T> {
hasChildren?(element: TInput | T): boolean;
getChildren(element: TInput | T): T[];
}

View File

@@ -22,4 +22,4 @@ export class CollapseAllAction<TInput, T, TFilterData = void> extends Action {
return Promise.resolve();
}
}
}