Merge from vscode 073a24de05773f2261f89172987002dc0ae2f1cd (#9711)

This commit is contained in:
Anthony Dresser
2020-03-24 00:24:15 -07:00
committed by GitHub
parent 29741d684e
commit 89ef1b0c2e
226 changed files with 6161 additions and 3288 deletions

View File

@@ -7,7 +7,7 @@ import 'vs/css!./media/quickInput';
import { IQuickPickItem, IPickOptions, IInputOptions, IQuickNavigateConfiguration, IQuickPick, IQuickInput, IQuickInputButton, IInputBox, IQuickPickItemButtonEvent, QuickPickInput, IQuickPickSeparator, IKeyMods, IQuickPickAcceptEvent, NO_KEY_MODS } from 'vs/base/parts/quickinput/common/quickInput';
import * as dom from 'vs/base/browser/dom';
import { CancellationToken } from 'vs/base/common/cancellation';
import { QuickInputList } from './quickInputList';
import { QuickInputList, QuickInputListFocus } from './quickInputList';
import { QuickInputBox } from './quickInputBox';
import { KeyCode } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
@@ -364,7 +364,7 @@ class QuickInput extends Disposable implements IQuickInput {
readonly onDispose = this.onDisposeEmitter.event;
public dispose(): void {
dispose(): void {
this.hide();
this.onDisposeEmitter.fire();
@@ -391,6 +391,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private _matchOnLabel = true;
private _sortByLabel = true;
private _autoFocusOnList = true;
private _autoFocusSecondEntry = false;
private _activeItems: T[] = [];
private activeItemsUpdated = false;
private activeItemsToConfirm: T[] | null = [];
@@ -408,6 +409,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private _customButtonLabel: string | undefined;
private _customButtonHover: string | undefined;
private _quickNavigate: IQuickNavigateConfiguration | undefined;
private _hideInput: boolean | undefined;
get quickNavigate() {
return this._quickNavigate;
@@ -460,10 +462,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
set items(items: Array<T | IQuickPickSeparator>) {
this._items = items;
this.itemsUpdated = true;
if (this._items.length === 0) {
// quick-navigate requires at least 1 item
this._quickNavigate = undefined;
}
this.update();
}
@@ -520,7 +518,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.update();
}
get autoFocusOnList() {
return this._autoFocusOnList;
}
@@ -530,6 +527,14 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.update();
}
get autoFocusSecondEntry() {
return this._autoFocusSecondEntry;
}
set autoFocusSecondEntry(autoFocusSecondEntry: boolean) {
this._autoFocusSecondEntry = autoFocusSecondEntry;
}
get activeItems() {
return this._activeItems;
}
@@ -614,14 +619,23 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.update();
}
public inputHasFocus(): boolean {
inputHasFocus(): boolean {
return this.visible ? this.ui.inputBox.hasFocus() : false;
}
public focusOnInput() {
focusOnInput() {
this.ui.inputBox.setFocus();
}
get hideInput() {
return !!this._hideInput;
}
set hideInput(hideInput: boolean) {
this._hideInput = hideInput;
this.update();
}
onDidChangeSelection = this.onDidChangeSelectionEmitter.event;
onDidTriggerItemButton = this.onDidTriggerItemButtonEmitter.event;
@@ -629,7 +643,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private trySelectFirst() {
if (this.autoFocusOnList) {
if (!this.ui.isScreenReaderOptimized() && !this.canSelectMany) {
this.ui.list.focus('First');
this.ui.list.focus(QuickInputListFocus.First);
}
}
}
@@ -656,7 +670,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.visibleDisposables.add(this.ui.inputBox.onKeyDown(event => {
switch (event.keyCode) {
case KeyCode.DownArrow:
this.ui.list.focus('Next');
this.ui.list.focus(QuickInputListFocus.Next);
if (this.canSelectMany) {
this.ui.list.domFocus();
}
@@ -664,9 +678,9 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
break;
case KeyCode.UpArrow:
if (this.ui.list.getFocusedElements().length) {
this.ui.list.focus('Previous');
this.ui.list.focus(QuickInputListFocus.Previous);
} else {
this.ui.list.focus('Last');
this.ui.list.focus(QuickInputListFocus.Last);
}
if (this.canSelectMany) {
this.ui.list.domFocus();
@@ -675,9 +689,9 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
break;
case KeyCode.PageDown:
if (this.ui.list.getFocusedElements().length) {
this.ui.list.focus('NextPage');
this.ui.list.focus(QuickInputListFocus.NextPage);
} else {
this.ui.list.focus('First');
this.ui.list.focus(QuickInputListFocus.First);
}
if (this.canSelectMany) {
this.ui.list.domFocus();
@@ -686,9 +700,9 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
break;
case KeyCode.PageUp:
if (this.ui.list.getFocusedElements().length) {
this.ui.list.focus('PreviousPage');
this.ui.list.focus(QuickInputListFocus.PreviousPage);
} else {
this.ui.list.focus('Last');
this.ui.list.focus(QuickInputListFocus.Last);
}
if (this.canSelectMany) {
this.ui.list.domFocus();
@@ -721,7 +735,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.onDidAcceptEmitter.fire({ inBackground: false });
}));
this.visibleDisposables.add(this.ui.onDidCustom(() => {
this.onDidCustomEmitter.fire(undefined);
this.onDidCustomEmitter.fire();
}));
this.visibleDisposables.add(this.ui.list.onDidChangeFocus(focusedItems => {
if (this.activeItemsUpdated) {
@@ -768,7 +782,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private registerQuickNavigation() {
return dom.addDisposableListener(this.ui.container, dom.EventType.KEY_UP, e => {
if (this.canSelectMany || !this.quickNavigate) {
if (this.canSelectMany || !this._quickNavigate) {
return;
}
@@ -776,7 +790,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
const keyCode = keyboardEvent.keyCode;
// Select element when keys are pressed that signal it
const quickNavKeys = this.quickNavigate.keybindings;
const quickNavKeys = this._quickNavigate.keybindings;
const wasTriggerKeyPressed = quickNavKeys.some(k => {
const [firstPart, chordPart] = k.getParts();
if (chordPart) {
@@ -806,10 +820,16 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
return false;
});
if (wasTriggerKeyPressed && this.activeItems[0]) {
this._selectedItems = [this.activeItems[0]];
this.onDidChangeSelectionEmitter.fire(this.selectedItems);
this.onDidAcceptEmitter.fire({ inBackground: false });
if (wasTriggerKeyPressed) {
if (this.activeItems[0]) {
this._selectedItems = [this.activeItems[0]];
this.onDidChangeSelectionEmitter.fire(this.selectedItems);
this.onDidAcceptEmitter.fire({ inBackground: false });
}
// Unset quick navigate after press. It is only valid once
// and should not result in any behaviour change afterwards
// if the picker remains open because there was no active item
this._quickNavigate = undefined;
}
});
}
@@ -818,11 +838,21 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
if (!this.visible) {
return;
}
dom.toggleClass(this.ui.container, 'quick-navigate-mode', !!this._quickNavigate);
const ok = this.ok === 'default' ? this.canSelectMany : this.ok;
const visibilities: Visibilities = this.canSelectMany ?
{ title: !!this.title || !!this.step, description: !!this.description, checkAll: true, inputBox: !this._quickNavigate, progressBar: !this._quickNavigate, visibleCount: true, count: true, ok, list: true, message: !!this.validationMessage, customButton: this.customButton } :
{ title: !!this.title || !!this.step, description: !!this.description, inputBox: !this._quickNavigate, progressBar: !this._quickNavigate, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok };
const hideInput = !!this._hideInput && this._items.length > 0; // do not allow to hide input without items
dom.toggleClass(this.ui.container, 'hidden-input', hideInput);
const visibilities: Visibilities = {
title: !!this.title || !!this.step,
description: !!this.description,
checkAll: this.canSelectMany,
inputBox: !hideInput,
progressBar: !hideInput,
visibleCount: true,
count: this.canSelectMany,
ok: this.ok === 'default' ? this.canSelectMany : this.ok,
list: true,
message: !!this.validationMessage,
customButton: this.customButton
};
this.ui.setVisibilities(visibilities);
super.update();
if (this.ui.inputBox.value !== this.value) {
@@ -844,17 +874,16 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.ui.list.sortByLabel = this.sortByLabel;
if (this.itemsUpdated) {
this.itemsUpdated = false;
const previousItemCount = this.ui.list.getElementsCount();
this.ui.list.setElements(this.items);
this.ui.list.filter(this.filterValue(this.ui.inputBox.value));
this.ui.checkAll.checked = this.ui.list.getAllVisibleChecked();
this.ui.visibleCount.setCount(this.ui.list.getVisibleCount());
this.ui.count.setCount(this.ui.list.getCheckedCount());
this.trySelectFirst();
if (this._quickNavigate && previousItemCount === 0 && this.items.length > 1) {
// quick navigate: automatically focus the second entry
// so that upon release the item is picked directly
this.ui.list.focus('Next');
if (this._autoFocusSecondEntry) {
this.ui.list.focus(QuickInputListFocus.Second);
this._autoFocusSecondEntry = false; // only valid once, then unset
} else {
this.trySelectFirst();
}
}
if (this.ui.container.classList.contains('show-checkboxes') !== !!this.canSelectMany) {
@@ -985,7 +1014,7 @@ class InputBox extends QuickInput implements IInputBox {
this._value = value;
this.onDidValueChangeEmitter.fire(value);
}));
this.visibleDisposables.add(this.ui.onDidAccept(() => this.onDidAcceptEmitter.fire(undefined)));
this.visibleDisposables.add(this.ui.onDidAccept(() => this.onDidAcceptEmitter.fire()));
this.valueSelectionUpdated = true;
}
super.show();
@@ -1039,10 +1068,12 @@ export class QuickInputController extends Disposable {
private parentElement: HTMLElement;
private styles: IQuickInputStyles;
private onShowEmitter = new Emitter<void>();
readonly onShow = this.onShowEmitter.event;
private onHideEmitter = new Emitter<void>();
public onShow = this.onShowEmitter.event;
public onHide = this.onHideEmitter.event;
readonly onHide = this.onHideEmitter.event;
constructor(private options: IQuickInputOptions) {
super();
@@ -1517,7 +1548,7 @@ export class QuickInputController extends Disposable {
}
}
public hide(focusLost?: boolean) {
hide(focusLost?: boolean) {
const controller = this.controller;
if (controller) {
this.controller = null;
@@ -1544,14 +1575,21 @@ export class QuickInputController extends Disposable {
navigate(next: boolean, quickNavigate?: IQuickNavigateConfiguration) {
if (this.isDisplayed() && this.getUI().list.isDisplayed()) {
this.getUI().list.focus(next ? 'Next' : 'Previous');
this.getUI().list.focus(next ? QuickInputListFocus.Next : QuickInputListFocus.Previous);
if (quickNavigate && this.controller instanceof QuickPick) {
this.controller.quickNavigate = quickNavigate;
}
}
}
async accept() {
async accept(keyMods: IKeyMods = { alt: false, ctrlCmd: false }) {
// When accepting the item programmatically, it is important that
// we update `keyMods` either from the provided set or unset it
// because the accept did not happen from mouse or keyboard
// interaction on the list itself
this.keyMods.alt = keyMods.alt;
this.keyMods.ctrlCmd = keyMods.ctrlCmd;
this.onDidAcceptEmitter.fire();
}
@@ -1583,7 +1621,7 @@ export class QuickInputController extends Disposable {
}
}
public applyStyles(styles: IQuickInputStyles) {
applyStyles(styles: IQuickInputStyles) {
this.styles = styles;
this.updateStyles();
}