Merge from vscode 709a07d51919d3266ca71699c6ddfb2d3547c0e1 (#6575)

This commit is contained in:
Chris LaFreniere
2019-08-02 21:06:44 -07:00
committed by GitHub
parent 402b50c03b
commit 62d2fb534d
103 changed files with 726 additions and 374 deletions

View File

@@ -12,10 +12,29 @@
margin-left: 2px;
}
/* Deal with overflow */
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-value {
max-width: 90%;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget .setting-list-sibling {
max-width: 10%;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-sibling {
display: inline-block;
line-height: 22px;
}
/* Use monospace to display glob patterns in exclude widget */
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-value,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget .setting-list-sibling {
font-family: var(--monaco-monospace-font);
}
@@ -35,6 +54,7 @@
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row {
position: relative;
max-height: 22px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-row:focus {
@@ -102,6 +122,8 @@
margin-right: 10px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget {
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-widget,
.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-list .setting-list-exclude-widget {
margin-bottom: 1px;
padding: 1px;
}

View File

@@ -978,8 +978,15 @@ export class SettingsEditor2 extends BaseEditor {
// If a single setting is being refreshed, it's ok to refresh now if that is not the focused setting
if (key) {
const focusedKey = focusedSetting.getAttribute(AbstractSettingRenderer.SETTING_KEY_ATTR);
if (focusedKey === key &&
!DOM.hasClass(focusedSetting, 'setting-item-list')) { // update `list`s live, as they have a separate "submit edit" step built in before this
/**
* Update `list`s live if focused item is whole list or list item,
* as they have a separate "submit edit" step built in before this
*/
if (
focusedKey === key &&
!DOM.hasClass(focusedSetting, 'setting-item-list') &&
!DOM.hasClass(focusedSetting, 'setting-item-contents')
) {
this.updateModifiedLabelForKey(key);
this.scheduleRefresh(focusedSetting, key);

View File

@@ -698,32 +698,46 @@ export class SettingArrayRenderer extends AbstractSettingRenderer implements ITr
private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void {
if (template.context) {
const newValue: any[] | undefined = isArray(template.context.scopeValue)
? [...template.context.scopeValue]
: [...template.context.value];
let newValue: any[] = [];
if (isArray(template.context.scopeValue)) {
newValue = [...template.context.scopeValue];
} else if (isArray(template.context.value)) {
newValue = [...template.context.value];
}
// Delete value
if (e.removeIndex) {
if (!e.value && e.originalValue && e.removeIndex > -1) {
newValue.splice(e.removeIndex, 1);
if (e.targetIndex !== undefined) {
// Delete value
if (!e.value && e.originalValue && e.targetIndex > -1) {
newValue.splice(e.targetIndex, 1);
}
}
// Add value
else if (e.value && !e.originalValue) {
newValue.push(e.value);
}
// Update value
else if (e.value && e.originalValue) {
const valueIndex = newValue.indexOf(e.originalValue);
if (valueIndex > -1) {
newValue[valueIndex] = e.value;
// Update value
else if (e.value && e.originalValue) {
if (e.targetIndex > -1) {
newValue[e.targetIndex] = e.value;
}
// For some reason, we are updating and cannot find original value
// Just append the value in this case
else {
newValue.push(e.value);
}
}
// For some reason, we are updating and cannot find original value
// Just append the value in this case
else {
// Add value
else if (e.value && !e.originalValue && e.targetIndex >= newValue.length) {
newValue.push(e.value);
}
}
if (
template.context.defaultValue &&
isArray(template.context.defaultValue) &&
template.context.defaultValue.length === newValue.length &&
template.context.defaultValue.join() === newValue.join()
) {
return this._onDidChangeSetting.fire({
key: template.context.setting.key,
value: undefined, // reset setting
type: template.context.valueType
});
}
this._onDidChangeSetting.fire({
key: template.context.setting.key,

View File

@@ -20,6 +20,7 @@ import { foreground, inputBackground, inputBorder, inputForeground, listActiveSe
import { attachButtonStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { disposableTimeout } from 'vs/base/common/async';
import { isUndefinedOrNull } from 'vs/base/common/types';
const $ = DOM.$;
export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "(For settings editor preview) The foreground color for a section header or active title."));
@@ -131,14 +132,16 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
}
});
type EditKey = 'none' | 'create' | number;
export class ListSettingListModel {
private _dataItems: IListDataItem[] = [];
private _editKey: string | null;
private _editKey: EditKey;
private _selectedIdx: number | null;
get items(): IListViewItem[] {
const items = this._dataItems.map((item, i) => {
const editing = item.value === this._editKey;
const editing = typeof this._editKey === 'number' && this._editKey === i;
return <IListViewItem>{
...item,
editing,
@@ -146,7 +149,7 @@ export class ListSettingListModel {
};
});
if (this._editKey === '') {
if (this._editKey === 'create') {
items.push({
editing: true,
selected: true,
@@ -158,7 +161,7 @@ export class ListSettingListModel {
return items;
}
setEditKey(key: string | null): void {
setEditKey(key: EditKey): void {
this._editKey = key;
}
@@ -195,7 +198,7 @@ export interface IListChangeEvent {
originalValue: string;
value?: string;
sibling?: string;
removeIndex?: number;
targetIndex?: number;
}
export class ListSettingWidget extends Disposable {
@@ -218,7 +221,8 @@ export class ListSettingWidget extends Disposable {
) {
super();
this.listElement = DOM.append(container, $('.setting-list-widget'));
this.listElement = DOM.append(container, $('div'));
this.getContainerClasses().forEach(c => this.listElement.classList.add(c));
this.listElement.setAttribute('tabindex', '0');
DOM.append(container, this.renderAddButton());
this.renderList();
@@ -228,13 +232,19 @@ export class ListSettingWidget extends Disposable {
this._register(DOM.addStandardDisposableListener(this.listElement, 'keydown', (e: KeyboardEvent) => {
if (e.keyCode === KeyCode.UpArrow) {
const selectedIndex = this.model.getSelected();
this.model.selectPrevious();
this.renderList();
if (this.model.getSelected() !== selectedIndex) {
this.renderList();
}
e.preventDefault();
e.stopPropagation();
} else if (e.keyCode === KeyCode.DownArrow) {
const selectedIndex = this.model.getSelected();
this.model.selectNext();
this.renderList();
if (this.model.getSelected() !== selectedIndex) {
this.renderList();
}
e.preventDefault();
e.stopPropagation();
}
@@ -259,6 +269,10 @@ export class ListSettingWidget extends Disposable {
};
}
protected getContainerClasses() {
return ['setting-list-widget'];
}
setValue(listData: IListDataItem[]): void {
this.model.setValue(listData);
this.renderList();
@@ -288,7 +302,7 @@ export class ListSettingWidget extends Disposable {
const item = this.model.items[targetIdx];
if (item) {
this.editSetting(item.value);
this.editSetting(targetIdx);
e.preventDefault();
e.stopPropagation();
}
@@ -342,30 +356,30 @@ export class ListSettingWidget extends Disposable {
enabled: true,
id: 'workbench.action.removeListItem',
tooltip: this.getLocalizedStrings().deleteActionTooltip,
run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, removeIndex: idx })
run: () => this._onDidChangeList.fire({ originalValue: key, value: undefined, targetIndex: idx })
};
}
private createEditAction(key: string): IAction {
private createEditAction(idx: number): IAction {
return <IAction>{
class: 'setting-listAction-edit',
enabled: true,
id: 'workbench.action.editListItem',
tooltip: this.getLocalizedStrings().editActionTooltip,
run: () => {
this.editSetting(key);
this.editSetting(idx);
}
};
}
private editSetting(key: string): void {
this.model.setEditKey(key);
private editSetting(idx: number): void {
this.model.setEditKey(idx);
this.renderList();
}
private renderItem(item: IListViewItem, idx: number, listFocused: boolean): HTMLElement {
return item.editing ?
this.renderEditItem(item) :
this.renderEditItem(item, idx) :
this.renderDataItem(item, idx, listFocused);
}
@@ -384,7 +398,7 @@ export class ListSettingWidget extends Disposable {
siblingElement.textContent = item.sibling ? ('when: ' + item.sibling) : null;
actionBar.push([
this.createEditAction(item.value),
this.createEditAction(idx),
this.createDeleteAction(item.value, idx)
], { icon: true, label: false });
@@ -412,24 +426,25 @@ export class ListSettingWidget extends Disposable {
this._register(attachButtonStyler(startAddButton, this.themeService));
this._register(startAddButton.onDidClick(() => {
this.model.setEditKey('');
this.model.setEditKey('create');
this.renderList();
}));
return rowElement;
}
private renderEditItem(item: IListViewItem): HTMLElement {
private renderEditItem(item: IListViewItem, idx: number): HTMLElement {
const rowElement = $('.setting-list-edit-row');
const onSubmit = (edited: boolean) => {
this.model.setEditKey(null);
this.model.setEditKey('none');
const value = valueInput.value.trim();
if (edited && value) {
if (edited && !isUndefinedOrNull(value)) {
this._onDidChangeList.fire({
originalValue: item.value,
value: value,
sibling: siblingInput && siblingInput.value.trim()
sibling: siblingInput && siblingInput.value.trim(),
targetIndex: idx
});
}
this.renderList();
@@ -514,6 +529,10 @@ export class ExcludeSettingWidget extends ListSettingWidget {
settingListRowSiblingHintLabel: localize('excludeSiblingHintLabel', "Exclude files matching `{0}`, only when a file matching `{1}` is present", pattern, sibling)
};
}
protected getContainerClasses() {
return ['setting-list-exclude-widget'];
}
}
export interface IListDataItem {