Merge VS Code 1.31.1 (#4283)

This commit is contained in:
Matt Irvine
2019-03-15 13:09:45 -07:00
committed by GitHub
parent 7d31575149
commit 86bac90001
1716 changed files with 53308 additions and 48375 deletions

View File

@@ -6,7 +6,7 @@
import 'vs/css!./selectBoxCustom';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { Event, Emitter, chain } from 'vs/base/common/event';
import { Event, Emitter } from 'vs/base/common/event';
import { KeyCode, KeyCodeUtils } from 'vs/base/common/keyCodes';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import * as dom from 'vs/base/browser/dom';
@@ -16,7 +16,7 @@ import { List } from 'vs/base/browser/ui/list/listWidget';
import { IListVirtualDelegate, IListRenderer, IListEvent } from 'vs/base/browser/ui/list/list';
import { domEvent } from 'vs/base/browser/event';
import { ScrollbarVisibility } from 'vs/base/common/scrollable';
import { ISelectBoxDelegate, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { ISelectBoxDelegate, ISelectOptionItem, ISelectBoxOptions, ISelectBoxStyles, ISelectData } from 'vs/base/browser/ui/selectBox/selectBox';
import { isMacintosh } from 'vs/base/common/platform';
import { renderMarkdown } from 'vs/base/browser/htmlContentRenderer';
@@ -24,16 +24,11 @@ const $ = dom.$;
const SELECT_OPTION_ENTRY_TEMPLATE_ID = 'selectOption.entry.template';
export interface ISelectOptionItem {
optionText: string;
optionDescriptionText?: string;
optionDisabled: boolean;
}
interface ISelectListTemplateData {
root: HTMLElement;
optionText: HTMLElement;
optionDescriptionText: HTMLElement;
text: HTMLElement;
itemDescription: HTMLElement;
decoratorRight: HTMLElement;
disposables: IDisposable[];
}
@@ -47,29 +42,32 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
const data = <ISelectListTemplateData>Object.create(null);
data.disposables = [];
data.root = container;
data.optionText = dom.append(container, $('.option-text'));
data.optionDescriptionText = dom.append(container, $('.option-text-description'));
dom.addClass(data.optionDescriptionText, 'visually-hidden');
data.text = dom.append(container, $('.option-text'));
data.decoratorRight = dom.append(container, $('.option-decorator-right'));
data.itemDescription = dom.append(container, $('.option-text-description'));
dom.addClass(data.itemDescription, 'visually-hidden');
return data;
}
renderElement(element: ISelectOptionItem, index: number, templateData: ISelectListTemplateData): void {
const data = <ISelectListTemplateData>templateData;
const optionText = (<ISelectOptionItem>element).optionText;
const optionDisabled = (<ISelectOptionItem>element).optionDisabled;
const text = (<ISelectOptionItem>element).text;
const decoratorRight = (<ISelectOptionItem>element).decoratorRight;
const isDisabled = (<ISelectOptionItem>element).isDisabled;
data.optionText.textContent = optionText;
data.text.textContent = text;
data.decoratorRight.innerText = (!!decoratorRight ? decoratorRight : '');
if (typeof element.optionDescriptionText === 'string') {
const optionDescriptionId = (optionText.replace(/ /g, '_').toLowerCase() + '_description_' + data.root.id);
data.optionText.setAttribute('aria-describedby', optionDescriptionId);
data.optionDescriptionText.id = optionDescriptionId;
data.optionDescriptionText.innerText = element.optionDescriptionText;
if (typeof element.description === 'string') {
const itemDescriptionId = (text.replace(/ /g, '_').toLowerCase() + '_description_' + data.root.id);
data.text.setAttribute('aria-describedby', itemDescriptionId);
data.itemDescription.id = itemDescriptionId;
data.itemDescription.innerText = element.description;
}
// pseudo-select disabled option
if (optionDisabled) {
if (isDisabled) {
dom.addClass((<HTMLElement>data.root), 'option-disabled');
} else {
// Make sure we do class removal from prior template rendering
@@ -77,10 +75,6 @@ class SelectListRenderer implements IListRenderer<ISelectOptionItem, ISelectList
}
}
disposeElement(): void {
// noop
}
disposeTemplate(templateData: ISelectListTemplateData): void {
templateData.disposables = dispose(templateData.disposables);
}
@@ -96,9 +90,8 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private selectBoxOptions: ISelectBoxOptions;
// {{SQL CARBON EDIT}}
public selectElement: HTMLSelectElement;
private options: string[];
private options: ISelectOptionItem[];
private selected: number;
private disabledOptionIndex: number;
private readonly _onDidSelect: Emitter<ISelectData>;
private toDispose: IDisposable[];
private styles: ISelectBoxStyles;
@@ -111,13 +104,13 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private widthControlElement: HTMLElement;
private _currentSelection: number;
private _dropDownPosition: AnchorPosition;
private detailsProvider: (index: number) => { details: string, isMarkdown: boolean };
private _hasDetails: boolean = false;
private selectionDetailsPane: HTMLElement;
private _skipLayout: boolean = false;
private _sticky: boolean = false; // for dev purposes only
constructor(options: string[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
constructor(options: ISelectOptionItem[], selected: number, contextViewProvider: IContextViewProvider, styles: ISelectBoxStyles, selectBoxOptions?: ISelectBoxOptions) {
this.toDispose = [];
this._isVisible = false;
@@ -252,19 +245,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return this._onDidSelect.event;
}
public setOptions(options: string[], selected?: number, disabled?: number): void {
public setOptions(options: ISelectOptionItem[], selected?: number): void {
if (!this.options || !arrays.equals(this.options, options)) {
this.options = options;
this.selectElement.options.length = 0;
this._hasDetails = false;
let i = 0;
this.options.forEach((option) => {
this.selectElement.add(this.createOption(option, i, disabled === i++));
this.options.forEach((option, index) => {
this.selectElement.add(this.createOption(option.text, index, option.isDisabled));
if (typeof option.description === 'string') {
this._hasDetails = true;
}
});
if (disabled !== undefined) {
this.disabledOptionIndex = disabled;
}
}
if (selected !== undefined) {
@@ -280,18 +272,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// Mirror options in drop-down
// Populate select list for non-native select mode
if (this.selectList && !!this.options) {
let listEntries: ISelectOptionItem[];
listEntries = [];
for (let index = 0; index < this.options.length; index++) {
const element = this.options[index];
let optionDisabled: boolean;
index === this.disabledOptionIndex ? optionDisabled = true : optionDisabled = false;
const optionDescription = this.detailsProvider ? this.detailsProvider(index) : { details: undefined, isMarkdown: false };
listEntries.push({ optionText: element, optionDisabled: optionDisabled, optionDescriptionText: optionDescription.details });
}
this.selectList.splice(0, this.selectList.length, listEntries);
this.selectList.splice(0, this.selectList.length, this.options);
}
}
@@ -315,10 +296,6 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectElement.setAttribute('aria-label', this.selectBoxOptions.ariaLabel);
}
public setDetailsProvider(provider: (index: number) => { details: string, isMarkdown: boolean }): void {
this.detailsProvider = provider;
}
public focus(): void {
if (this.selectElement) {
this.selectElement.focus();
@@ -353,6 +330,10 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row.focused:not(:hover) { color: ${this.styles.listFocusForeground} !important; }`);
}
if (this.styles.decoratorRightForeground) {
content.push(`.monaco-select-box-dropdown-container > .select-box-dropdown-list-container .monaco-list .monaco-list-row .option-decorator-right { color: ${this.styles.decoratorRightForeground} !important; }`);
}
if (this.styles.selectBackground && this.styles.selectBorder && !this.styles.selectBorder.equals(this.styles.selectBackground)) {
content.push(`.monaco-select-box-dropdown-container { border: 1px solid ${this.styles.selectBorder} } `);
content.push(`.monaco-select-box-dropdown-container > .select-box-details-pane.border-top { border-top: 1px solid ${this.styles.selectBorder} } `);
@@ -533,23 +514,16 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// Iterate over detailed descriptions, find max height
private measureMaxDetailsHeight(): number {
if (!this.detailsProvider) {
return 0;
}
let maxDetailsPaneHeight = 0;
let description = { details: '', isMarkdown: false };
this.options.forEach((option, index) => {
this.selectionDetailsPane.innerText = '';
description = this.detailsProvider ? this.detailsProvider(index) : { details: '', isMarkdown: false };
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
if (option.description) {
if (option.descriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(option.description));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = option.description;
}
this.selectionDetailsPane.style.display = 'block';
} else {
@@ -562,18 +536,19 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
});
// Reset description to selected
description = this.detailsProvider ? this.detailsProvider(this.selected) : { details: '', isMarkdown: false };
this.selectionDetailsPane.innerText = '';
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
this.selectionDetailsPane.innerText = '';
const description = this.options[this.selected].description || null;
const descriptionIsMarkdown = this.options[this.selected].descriptionIsMarkdown || null;
if (description) {
if (descriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = description;
}
this.selectionDetailsPane.style.display = 'block';
}
return maxDetailsPaneHeight;
}
@@ -610,7 +585,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectList.layout();
let listHeight = this.selectList.contentHeight;
const maxDetailsPaneHeight = this.measureMaxDetailsHeight();
const maxDetailsPaneHeight = this._hasDetails ? this.measureMaxDetailsHeight() : 0;
const minRequiredDropDownHeight = listHeight + verticalPadding + maxDetailsPaneHeight;
const maxVisibleOptionsBelow = ((Math.floor((maxSelectDropDownHeightBelow - verticalPadding - maxDetailsPaneHeight) / this.getHeight())));
@@ -702,7 +677,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectList.reveal(this.selectList.getFocus()[0] || 0);
}
if (this.detailsProvider) {
if (this._hasDetails) {
// Leave the selectDropDownContainer to size itself according to children (list + details) - #57447
this.selectList.getHTMLElement().style.height = (listHeight + verticalPadding) + 'px';
} else {
@@ -727,14 +702,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
if (container && !!this.options) {
let longest = 0;
let longestLength = 0;
for (let index = 0; index < this.options.length; index++) {
if (this.options[index].length > this.options[longest].length) {
this.options.forEach((option, index) => {
const len = option.text.length + (!!option.decoratorRight ? option.decoratorRight.length : 0);
if (len > longestLength) {
longest = index;
longestLength = len;
}
}
});
container.innerHTML = this.options[longest];
container.innerHTML = this.options[longest].text + (!!this.options[longest].decoratorRight ? (this.options[longest].decoratorRight + ' ') : '');
elementWidth = dom.getTotalWidth(container);
}
@@ -763,14 +742,13 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selectList = new List(this.selectDropDownListContainer, this, [this.listRenderer], {
ariaLabel: this.selectBoxOptions.ariaLabel,
useShadows: false,
selectOnMouseDown: false,
verticalScrollMode: ScrollbarVisibility.Visible,
keyboardSupport: false,
mouseSupport: false
});
// SetUp list keyboard controller - control navigation, disabled items, focus
const onSelectDropDownKeyDown = chain(domEvent(this.selectDropDownListContainer, 'keydown'))
const onSelectDropDownKeyDown = Event.chain(domEvent(this.selectDropDownListContainer, 'keydown'))
.filter(() => this.selectList.length > 0)
.map(e => new StandardKeyboardEvent(e));
@@ -786,7 +764,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// SetUp list mouse controller - control navigation, disabled items, focus
chain(domEvent(this.selectList.getHTMLElement(), 'mouseup'))
Event.chain(domEvent(this.selectList.getHTMLElement(), 'mouseup'))
.filter(() => this.selectList.length > 0)
.on(e => this.onMouseUp(e), this, this.toDispose);
@@ -809,12 +787,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
dom.EventHelper.stop(e);
// Check our mouse event is on an option (not scrollbar)
if (!e.toElement.classList.contains('option-text')) {
const target = <Element>e.target;
if (!target) {
return;
}
const listRowElement = e.toElement.parentElement;
// Check our mouse event is on an option (not scrollbar)
if (!!target.classList.contains('slider')) {
return;
}
const listRowElement = target.closest('.monaco-list-row');
if (!listRowElement) {
return;
}
@@ -839,7 +823,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this._onDidSelect.fire({
index: this.selectElement.selectedIndex,
selected: this.options[this.selected]
selected: this.options[this.selected].text
});
}
}
@@ -871,9 +855,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
}
};
const renderedMarkdown = renderMarkdown({ value: text }, {
actionHandler: this.selectBoxOptions.markdownActionHandler
});
const renderedMarkdown = renderMarkdown({ value: text });
renderedMarkdown.classList.add('select-box-description-markdown');
cleanRenderedMarkdown(renderedMarkdown);
@@ -884,18 +866,20 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// List Focus Change - passive - update details pane with newly focused element's data
private onListFocus(e: IListEvent<ISelectOptionItem>) {
// Skip during initial layout
if (!this._isVisible) {
if (!this._isVisible || !this._hasDetails) {
return;
}
this.selectionDetailsPane.innerText = '';
const selectedIndex = e.indexes[0];
let description = this.detailsProvider ? this.detailsProvider(selectedIndex) : { details: '', isMarkdown: false };
if (description.details) {
if (description.isMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description.details));
const description = this.options[selectedIndex].description || null;
const descriptionIsMarkdown = this.options[selectedIndex].descriptionIsMarkdown || null;
if (description) {
if (descriptionIsMarkdown) {
this.selectionDetailsPane.appendChild(this.renderDescriptionMarkdown(description));
} else {
this.selectionDetailsPane.innerText = description.details;
this.selectionDetailsPane.innerText = description;
}
this.selectionDetailsPane.style.display = 'block';
} else {
@@ -929,7 +913,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this._currentSelection = this.selected;
this._onDidSelect.fire({
index: this.selectElement.selectedIndex,
selected: this.options[this.selected]
selected: this.options[this.selected].text
});
}
@@ -939,14 +923,18 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
// List navigation - have to handle a disabled option (jump over)
private onDownArrow(): void {
if (this.selected < this.options.length - 1) {
// Skip disabled options
if ((this.selected + 1) === this.disabledOptionIndex && this.options.length > this.selected + 2) {
const nextOptionDisabled = this.options[this.selected + 1].isDisabled;
if (nextOptionDisabled && this.options.length > this.selected + 2) {
this.selected += 2;
} else if ((this.selected + 1) === this.disabledOptionIndex) {
} else if (nextOptionDisabled) {
return;
} else {
this.selected++;
}
// Set focus/selection - only fire event when closing drop-down or on blur
this.select(this.selected);
this.selectList.setFocus([this.selected]);
@@ -957,7 +945,8 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
private onUpArrow(): void {
if (this.selected > 0) {
// Skip disabled options
if ((this.selected - 1) === this.disabledOptionIndex && this.selected > 1) {
const previousOptionDisabled = this.options[this.selected - 1].isDisabled;
if (previousOptionDisabled && this.selected > 1) {
this.selected -= 2;
} else {
this.selected--;
@@ -979,7 +968,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selected = this.selectList.getFocus()[0];
// Shift selection down if we land on a disabled option
if (this.selected === this.disabledOptionIndex && this.selected < this.options.length - 1) {
if (this.options[this.selected].isDisabled && this.selected < this.options.length - 1) {
this.selected++;
this.selectList.setFocus([this.selected]);
}
@@ -998,7 +987,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
this.selected = this.selectList.getFocus()[0];
// Shift selection up if we land on a disabled option
if (this.selected === this.disabledOptionIndex && this.selected > 0) {
if (this.options[this.selected].isDisabled && this.selected > 0) {
this.selected--;
this.selectList.setFocus([this.selected]);
}
@@ -1014,7 +1003,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return;
}
this.selected = 0;
if (this.selected === this.disabledOptionIndex && this.selected > 1) {
if (this.options[this.selected].isDisabled && this.selected > 1) {
this.selected++;
}
this.selectList.setFocus([this.selected]);
@@ -1029,7 +1018,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
return;
}
this.selected = this.options.length - 1;
if (this.selected === this.disabledOptionIndex && this.selected > 1) {
if (this.options[this.selected].isDisabled && this.selected > 1) {
this.selected--;
}
this.selectList.setFocus([this.selected]);
@@ -1044,7 +1033,7 @@ export class SelectBoxList implements ISelectBoxDelegate, IListVirtualDelegate<I
for (let i = 0; i < this.options.length - 1; i++) {
optionIndex = (i + this.selected + 1) % this.options.length;
if (this.options[optionIndex].charAt(0).toUpperCase() === ch) {
if (this.options[optionIndex].text.charAt(0).toUpperCase() === ch && !this.options[optionIndex].isDisabled) {
this.select(optionIndex);
this.selectList.setFocus([optionIndex]);
this.selectList.reveal(this.selectList.getFocus()[0]);