Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)

This commit is contained in:
Anthony Dresser
2019-03-26 11:43:38 -07:00
committed by GitHub
parent b1393ae615
commit 0d8ef9583b
268 changed files with 5947 additions and 3422 deletions

View File

@@ -0,0 +1 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.784 8L13 11.217 11.215 13 8.001 9.786 4.785 13 3 11.216l3.214-3.215L3 4.785 4.784 3 8 6.216 11.216 3 13 4.785 9.784 8.001z" fill="#C5C5C5"/></svg>

After

Width:  |  Height:  |  Size: 253 B

View File

@@ -0,0 +1 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M9.784 8L13 11.217 11.215 13 8.001 9.786 4.785 13 3 11.216l3.214-3.215L3 4.785 4.784 3 8 6.216 11.216 3 13 4.785 9.784 8.001z" fill="#424242"/></svg>

After

Width:  |  Height:  |  Size: 253 B

View File

@@ -0,0 +1,154 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/** Dialog: Modal Block */
.monaco-workbench .dialog-modal-block {
position: fixed;
height: 100%;
width: 100%;
left:0;
top:0;
z-index: 2000;
}
/** Dialog: Container */
.monaco-workbench .dialog-box {
position: absolute;
display: flex;
flex-direction: column-reverse;
top: 200px;
left: 50%;
margin-left: -250px;
width: 500px;
min-height: 75px;
padding: 5px;
}
/** Dialog: Title Actions Row */
.monaco-workbench .dialog-box .dialog-toolbar-row {
padding-right: 1px;
}
.monaco-workbench .dialog-box .action-label {
height: 16px;
min-width: 16px;
background-size: 16px;
background-position: 50%;
background-repeat: no-repeat;
margin: 0px;
margin-left: 4px;
}
.monaco-workbench .dialog-box .dialog-close-action {
background: url('close.svg') center center no-repeat;
}
.vs-dark .monaco-workbench .dialog-box .dialog-close-action,
.hc-black .monaco-workbench .dialog-box .dialog-close-action {
background: url('close-inverse.svg') center center no-repeat;
}
/** Dialog: Message Row */
.monaco-workbench .dialog-box .dialog-message-row {
display: flex;
flex-grow: 1;
padding: 10px 15px 20px;
}
.monaco-workbench .dialog-box .dialog-message-row .dialog-icon {
flex: 0 0 30px;
padding-right: 4px;
padding-left: 4px;
background-position: center;
background-repeat: no-repeat;
}
.vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info {
background-image: url('info.svg');
}
.vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning {
background-image: url('warning.svg');
}
.vs .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error {
background-image: url('error.svg');
}
.vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info,
.hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-info {
background-image: url('info-inverse.svg');
}
.vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning,
.hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-warning {
background-image: url('warning-inverse.svg');
}
.vs-dark .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error,
.hc-black .monaco-workbench .dialog-box .dialog-message-row .dialog-icon.icon-error {
background-image: url('error-inverse.svg');
}
/** Dialog: Message Container */
.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container {
display: flex;
flex-direction: column;
overflow: hidden;
text-overflow: ellipsis;
padding-left: 20px;
user-select: text;
word-wrap: break-word; /* never overflow long words, but break to next line */
white-space: normal;
}
/** Dialog: Message */
.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container .dialog-message {
line-height: 22px;
font-size: 18px;
flex: 1; /* let the message always grow */
white-space: normal;
word-wrap: break-word; /* never overflow long words, but break to next line */
padding-bottom: 10px;
}
/** Dialog: Details */
.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container .dialog-message-detail {
line-height: 22px;
flex: 1; /* let the message always grow */
opacity: .9;
}
.monaco-workbench .dialog-box .dialog-message-row .dialog-message-container .dialog-message a:focus {
outline-width: 1px;
outline-style: solid;
}
/** Dialog: Buttons Row */
.monaco-workbench .dialog-box > .dialog-buttons-row {
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 1px;
overflow: hidden; /* buttons row should never overflow */
}
.monaco-workbench .monaco-workbench .dialog-box > .dialog-buttons-row {
display: flex;
}
/** Dialog: Buttons */
.monaco-workbench .monaco-workbench .dialog-box > .dialog-buttons-row > .dialog-buttons {
display: flex;
overflow: hidden;
}
.monaco-workbench .dialog-box > .dialog-buttons-row > .dialog-buttons > .monaco-button {
max-width: fit-content;
padding: 5px 10px;
margin: 4px 5px; /* allows button focus outline to be visible */
overflow: hidden;
text-overflow: ellipsis;
}

View File

@@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./dialog';
import * as nls from 'vs/nls';
import { Disposable } from 'vs/base/common/lifecycle';
import { $, hide, show, EventHelper, clearNode, removeClasses, addClass, removeNode } from 'vs/base/browser/dom';
import { domEvent } from 'vs/base/browser/event';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Color } from 'vs/base/common/color';
import { ButtonGroup, IButtonStyles } from 'vs/base/browser/ui/button/button';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
export interface IDialogOptions {
cancelId?: number;
detail?: string;
type?: 'none' | 'info' | 'error' | 'question' | 'warning';
}
export interface IDialogStyles extends IButtonStyles {
dialogForeground?: Color;
dialogBackground?: Color;
dialogShadow?: Color;
}
export class Dialog extends Disposable {
private element: HTMLElement | undefined;
private modal: HTMLElement | undefined;
private buttonsContainer: HTMLElement | undefined;
private iconElement: HTMLElement | undefined;
private toolbarContainer: HTMLElement | undefined;
private buttonGroup: ButtonGroup | undefined;
private styles: IDialogStyles | undefined;
constructor(private container: HTMLElement, private message: string, private buttons: string[], private options: IDialogOptions) {
super();
this.modal = this.container.appendChild($('.dialog-modal-block'));
this.element = this.modal.appendChild($('.dialog-box'));
hide(this.element);
const buttonsRowElement = this.element.appendChild($('.dialog-buttons-row'));
this.buttonsContainer = buttonsRowElement.appendChild($('.dialog-buttons'));
const messageRowElement = this.element.appendChild($('.dialog-message-row'));
this.iconElement = messageRowElement.appendChild($('.dialog-icon'));
const messageContainer = messageRowElement.appendChild($('.dialog-message-container'));
const messageElement = messageContainer.appendChild($('.dialog-message'));
messageElement.innerText = this.message;
if (this.options.detail) {
const messageDetailElement = messageContainer.appendChild($('.dialog-message-detail'));
messageDetailElement.innerText = this.options.detail;
}
const toolbarRowElement = this.element.appendChild($('.dialog-toolbar-row'));
this.toolbarContainer = toolbarRowElement.appendChild($('.dialog-toolbar'));
}
async show(): Promise<number> {
return new Promise<number>((resolve) => {
if (!this.element || !this.buttonsContainer || !this.iconElement || !this.toolbarContainer) {
resolve(0);
return;
}
if (this.modal) {
this._register(domEvent(this.modal, 'mousedown')(e => {
// Used to stop focusing of modal with mouse
EventHelper.stop(e, true);
}));
}
clearNode(this.buttonsContainer);
let focusedButton = 0;
this.buttonGroup = new ButtonGroup(this.buttonsContainer, this.buttons.length, { title: true });
this.buttonGroup.buttons.forEach((button, index) => {
button.label = mnemonicButtonLabel(this.buttons[index], true);
this._register(button.onDidClick(e => {
EventHelper.stop(e);
resolve(index);
}));
});
this._register(domEvent(this.element, 'keydown', true)((e: KeyboardEvent) => {
const evt = new StandardKeyboardEvent(e);
if (evt.equals(KeyCode.Enter)) {
return;
}
if (this.buttonGroup) {
if ((evt.shiftKey && evt.equals(KeyCode.Tab)) || evt.equals(KeyCode.LeftArrow)) {
focusedButton = focusedButton + this.buttonGroup.buttons.length - 1;
focusedButton = focusedButton % this.buttonGroup.buttons.length;
this.buttonGroup.buttons[focusedButton].focus();
} else if (evt.equals(KeyCode.Tab) || evt.equals(KeyCode.RightArrow)) {
focusedButton++;
focusedButton = focusedButton % this.buttonGroup.buttons.length;
this.buttonGroup.buttons[focusedButton].focus();
}
}
EventHelper.stop(e, true);
}));
this._register(domEvent(this.element, 'keyup', true)((e: KeyboardEvent) => {
EventHelper.stop(e, true);
const evt = new StandardKeyboardEvent(e);
if (evt.equals(KeyCode.Escape)) {
resolve(this.options.cancelId || 0);
}
}));
removeClasses(this.iconElement, 'icon-error', 'icon-warning', 'icon-info');
switch (this.options.type) {
case 'error':
addClass(this.iconElement, 'icon-error');
break;
case 'warning':
addClass(this.iconElement, 'icon-warning');
break;
case 'none':
case 'info':
case 'question':
default:
addClass(this.iconElement, 'icon-info');
break;
}
const actionBar = new ActionBar(this.toolbarContainer, {});
const action = new Action('dialog.close', nls.localize('dialogClose', "Close Dialog"), 'dialog-close-action', true, () => {
resolve(this.options.cancelId || 0);
return Promise.resolve();
});
actionBar.push(action, { icon: true, label: false, });
this.applyStyles();
show(this.element);
// Focus first element
this.buttonGroup.buttons[focusedButton].focus();
});
}
private applyStyles() {
if (this.styles) {
const style = this.styles;
const fgColor = style.dialogForeground ? `${style.dialogForeground}` : null;
const bgColor = style.dialogBackground ? `${style.dialogBackground}` : null;
const shadowColor = style.dialogShadow ? `0 0px 8px ${style.dialogShadow}` : null;
if (this.element) {
this.element.style.color = fgColor;
this.element.style.backgroundColor = bgColor;
this.element.style.boxShadow = shadowColor;
if (this.buttonGroup) {
this.buttonGroup.buttons.forEach(button => button.style(style));
}
}
}
}
style(style: IDialogStyles): void {
this.styles = style;
this.applyStyles();
}
dispose(): void {
super.dispose();
if (this.modal) {
removeNode(this.modal);
this.modal = undefined;
}
}
}

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#CACACC;}
.st1{fill:#E51400;}
.st2{fill:#FFFFFF;}
.st3{fill:#F6F6F6;fill-opacity:0;}
.st4{fill:#1A1A1A;}
</style>
<path id="outline_2_" class="st0" d="M-169.7-71.2c0,1.4-1.2,2.6-2.6,2.6c-1.4,0-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6
C-170.9-73.8-169.7-72.6-169.7-71.2z"/>
<path id="iconBg_2_" class="st1" d="M-172.3-73.5c-1.3,0-2.3,1-2.3,2.3s1,2.3,2.3,2.3s2.3-1,2.3-2.3S-171.1-73.5-172.3-73.5z
M-170.9-70.2l-0.5,0.5l-1-1l-1,1l-0.5-0.5l1-1l-1-1l0.5-0.5l1,1l1-1l0.5,0.5l-1,1L-170.9-70.2z"/>
<g id="iconFg_2_">
<path class="st2" d="M-171.9-71.2l1,1l-0.5,0.5l-1-1l-1,1l-0.5-0.5l1-1l-1-1l0.5-0.5l1,1l1-1l0.5,0.5L-171.9-71.2z"/>
</g>
<path id="canvas_1_" class="st3" d="M16,16H0V0h16V16z"/>
<path id="outline_1_" class="st4" d="M16,8c0,4.4-3.6,8-8,8s-8-3.6-8-8s3.6-8,8-8S16,3.6,16,8z"/>
<path id="iconBg_1_" class="st1" d="M8,1C4.1,1,1,4.1,1,8c0,3.9,3.1,7,7,7s7-3.1,7-7S11.9,1,8,1z M12.4,11L11,12.4l-3-3l-3,3L3.6,11
l3-3l-3-3L5,3.6l3,3l3-3L12.4,5l-3,3L12.4,11z"/>
<g id="iconFg_1_">
<path class="st2" d="M9.4,8l3,3L11,12.4l-3-3l-3,3L3.6,11l3-3l-3-3L5,3.6l3,3l3-3L12.4,5L9.4,8z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#CACACC;}
.st1{fill:#E51400;}
.st2{fill:#FFFFFF;}
.st3{fill:#F6F6F6;fill-opacity:0;}
</style>
<path id="outline" class="st0" d="M16,8c0,4.4-3.6,8-8,8s-8-3.6-8-8s3.6-8,8-8S16,3.6,16,8z"/>
<path id="iconBg" class="st1" d="M8,1C4.1,1,1,4.1,1,8c0,3.9,3.1,7,7,7s7-3.1,7-7S11.9,1,8,1z M12.4,11L11,12.4l-3-3l-3,3L3.6,11
l3-3l-3-3L5,3.6l3,3l3-3L12.4,5l-3,3L12.4,11z"/>
<g id="iconFg">
<path class="st2" d="M9.4,8l3,3L11,12.4l-3-3l-3,3L3.6,11l3-3l-3-3L5,3.6l3,3l3-3L12.4,5L9.4,8z"/>
</g>
<path id="canvas_4_" class="st3" d="M16,16H0V0h16V16z"/>
<path id="outline_2_" class="st0" d="M-192.7-71.2c0,1.4-1.2,2.6-2.6,2.6s-2.6-1.2-2.6-2.6s1.2-2.6,2.6-2.6S-192.7-72.6-192.7-71.2z
"/>
<path id="iconBg_2_" class="st1" d="M-195.4-73.5c-1.3,0-2.3,1-2.3,2.3s1,2.3,2.3,2.3c1.3,0,2.3-1,2.3-2.3S-194.1-73.5-195.4-73.5z
M-193.9-70.2l-0.5,0.5l-1-1l-1,1l-0.5-0.5l1-1l-1-1l0.5-0.5l1,1l1-1l0.5,0.5l-1,1L-193.9-70.2z"/>
<g id="iconFg_2_">
<path class="st2" d="M-194.9-71.2l1,1l-0.5,0.5l-1-1l-1,1l-0.5-0.5l1-1l-1-1l0.5-0.5l1,1l1-1l0.5,0.5L-194.9-71.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F6F6F6;fill-opacity:0;}
.st1{fill:#1A1A1A;}
.st2{fill:#1BA1E2;}
.st3{fill:#FFFFFF;}
</style>
<path id="canvas_1_" class="st0" d="M16,16H0V0h16V16z"/>
<path id="outline_1_" class="st1" d="M0,8c0-4.4,3.6-8,8-8s8,3.6,8,8s-3.6,8-8,8S0,12.4,0,8z"/>
<path id="iconBg_1_" class="st2" d="M8,1C4.1,1,1,4.1,1,8s3.1,7,7,7s7-3.1,7-7S11.9,1,8,1z M9,13H7V6h2V13z M9,5H7V3h2V5z"/>
<g id="iconFg_1_">
<path class="st3" d="M7,6h2v7H7V6z M7,5h2V3H7V5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 834 B

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F6F6F6;fill-opacity:0;}
.st1{fill:#CACACC;}
.st2{fill:#1BA1E2;}
.st3{fill:#FFFFFF;}
</style>
<path id="canvas" class="st0" d="M16,16H0V0h16V16z"/>
<path id="outline" class="st1" d="M0,8c0-4.4,3.6-8,8-8s8,3.6,8,8s-3.6,8-8,8S0,12.4,0,8z"/>
<path id="iconBg" class="st2" d="M8,1C4.1,1,1,4.1,1,8s3.1,7,7,7s7-3.1,7-7S11.8,1,8,1z M9,13H7V6h2V13z M9,5H7V3h2V5z"/>
<g id="iconFg">
<path class="st3" d="M7,6h2v7H7V6z M7,5h2V3H7V5z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 822 B

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F6F6F6;fill-opacity:0;}
.st1{fill:#1A1A1A;}
.st2{fill:#FFCC00;}
</style>
<title>StatusWarning_16x</title>
<path class="st0" d="M16,0v16H0V0H16z"/>
<path class="st1" d="M16,14l-2,2H2l-2-2L7,0h2L16,14z"/>
<path class="st2" d="M8.4,1H7.6L1.2,13.8L2.5,15h11l1.3-1.2L8.4,1z M9,13H7v-2h2V13z M9,10H7V5h2V10z"/>
<path d="M7,11h2v2H7V11z M7,5v5h2V5H7z"/>
</svg>

After

Width:  |  Height:  |  Size: 737 B

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve">
<style type="text/css">
.st0{fill:#F6F6F6;fill-opacity:0;}
.st1{fill:#CACACC;}
.st2{fill:#FFCC00;}
</style>
<title>StatusWarning_16x</title>
<path class="st0" d="M16,0v16H0V0H16z"/>
<path class="st1" d="M16,14l-2,2H2l-2-2L7,0h2L16,14z"/>
<path class="st2" d="M8.4,1H7.6L1.2,13.8L2.5,15h11l1.3-1.2L8.4,1z M9,13H7v-2h2V13z M9,10H7V5h2V10z"/>
<path d="M7,11h2v2H7V11z M7,5v5h2V5H7z"/>
</svg>

After

Width:  |  Height:  |  Size: 737 B

View File

@@ -7,7 +7,7 @@ import 'vs/css!./list';
import { localize } from 'vs/nls';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { isNumber } from 'vs/base/common/types';
import { range, firstIndex } from 'vs/base/common/arrays';
import { range, firstIndex, 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';
@@ -107,10 +107,8 @@ class TraitRenderer<T> implements IListRenderer<T, ITraitTemplateData>
class Trait<T> implements ISpliceable<boolean>, IDisposable {
/**
* Sorted indexes which have this trait.
*/
private indexes: number[];
private indexes: number[] = [];
private sortedIndexes: number[] = [];
private _onChange = new Emitter<ITraitChangeEvent>();
get onChange(): Event<ITraitChangeEvent> { return this._onChange.event; }
@@ -122,21 +120,19 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
return new TraitRenderer<T>(this);
}
constructor(private _trait: string) {
this.indexes = [];
}
constructor(private _trait: string) { }
splice(start: number, deleteCount: number, elements: boolean[]): void {
const diff = elements.length - deleteCount;
const end = start + deleteCount;
const indexes = [
...this.indexes.filter(i => i < start),
...this.sortedIndexes.filter(i => i < start),
...elements.map((hasTrait, i) => hasTrait ? i + start : -1).filter(i => i !== -1),
...this.indexes.filter(i => i >= end).map(i => i + diff)
...this.sortedIndexes.filter(i => i >= end).map(i => i + diff)
];
this.renderer.splice(start, deleteCount, elements.length);
this.set(indexes);
this._set(indexes, indexes);
}
renderIndex(index: number, container: HTMLElement): void {
@@ -154,10 +150,17 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
* @return The old indexes which had this trait.
*/
set(indexes: number[], browserEvent?: UIEvent): number[] {
const result = this.indexes;
this.indexes = indexes;
return this._set(indexes, [...indexes].sort(numericSort), browserEvent);
}
const toRender = disjunction(result, indexes);
private _set(indexes: number[], sortedIndexes: number[], browserEvent?: UIEvent): number[] {
const result = this.indexes;
const sortedResult = this.sortedIndexes;
this.indexes = indexes;
this.sortedIndexes = sortedIndexes;
const toRender = disjunction(sortedResult, indexes);
this.renderer.renderIndexes(toRender);
this._onChange.fire({ indexes, browserEvent });
@@ -169,7 +172,7 @@ class Trait<T> implements ISpliceable<boolean>, IDisposable {
}
contains(index: number): boolean {
return this.indexes.some(i => i === index);
return binarySearch(this.sortedIndexes, index, numericSort) >= 0;
}
dispose() {
@@ -1334,7 +1337,6 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
}
indexes = indexes.sort(numericSort);
this.selection.set(indexes, browserEvent);
}
@@ -1353,7 +1355,6 @@ export class List<T> implements ISpliceable<T>, IDisposable {
}
}
indexes = indexes.sort(numericSort);
this.focus.set(indexes, browserEvent);
}

View File

@@ -14,7 +14,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import { ITreeModel, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeFilter, ITreeNavigator, ICollapseStateChangeEvent, ITreeDragAndDrop, TreeDragOverBubble, TreeVisibility, TreeFilterResult, ITreeModelSpliceEvent } 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 } from 'vs/base/common/arrays';
import { range, equals, distinctES6 } 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';
@@ -924,7 +924,7 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
const additionalSelection: number[] = [];
elements.forEach((node, index) => {
if (this.selectionTrait.has(node)) {
if (this.focusTrait.has(node)) {
additionalFocus.push(start + index);
}
@@ -934,11 +934,11 @@ class TreeNodeList<T, TFilterData, TRef> extends List<ITreeNode<T, TFilterData>>
});
if (additionalFocus.length > 0) {
super.setFocus([...super.getFocus(), ...additionalFocus]);
super.setFocus(distinctES6([...super.getFocus(), ...additionalFocus]));
}
if (additionalSelection.length > 0) {
super.setSelection([...super.getSelection(), ...additionalSelection]);
super.setSelection(distinctES6([...super.getSelection(), ...additionalSelection]));
}
}