Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -25,7 +25,7 @@ import { Color, RGBA } from 'vs/base/common/color';
import { onUnexpectedError } from 'vs/base/common/errors';
import { Emitter, Event } from 'vs/base/common/event';
import { KeyCode } from 'vs/base/common/keyCodes';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { ISpliceable } from 'vs/base/common/sequence';
import { escapeRegExpCharacters, startsWith } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
@@ -42,13 +42,15 @@ import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attach
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ITOCEntry } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
import { ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
import { ExcludeSettingWidget, IExcludeChangeEvent, IExcludeDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { ListSettingWidget, IListChangeEvent, IListDataItem, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ExcludeSettingWidget } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { isArray } from 'vs/base/common/types';
const $ = DOM.$;
function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDataItem[] {
function getExcludeDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] {
const data = element.isConfigured ?
{ ...element.defaultValue, ...element.scopeValue } :
element.defaultValue;
@@ -61,12 +63,20 @@ function getExcludeDisplayValue(element: SettingsTreeSettingElement): IExcludeDa
return {
id: key,
pattern: key,
value: key,
sibling
};
});
}
function getListDisplayValue(element: SettingsTreeSettingElement): IListDataItem[] {
return element.value.map((key: string) => {
return {
value: key
};
});
}
export function resolveSettingsTree(tocData: ITOCEntry, coreSettingsGroups: ISettingsGroup[]): { tree: ITOCEntry, leftoverSettings: Set<ISetting> } {
const allSettings = getFlatSettings(coreSettingsGroups);
return {
@@ -210,8 +220,12 @@ interface ISettingComplexItemTemplate extends ISettingItemTemplate<void> {
button: Button;
}
interface ISettingListItemTemplate extends ISettingItemTemplate<void> {
listWidget: ListSettingWidget;
}
interface ISettingExcludeItemTemplate extends ISettingItemTemplate<void> {
excludeWidget: ExcludeSettingWidget;
excludeWidget: ListSettingWidget;
}
interface ISettingNewExtensionsTemplate extends IDisposableTemplate {
@@ -228,6 +242,7 @@ const SETTINGS_TEXT_TEMPLATE_ID = 'settings.text.template';
const SETTINGS_NUMBER_TEMPLATE_ID = 'settings.number.template';
const SETTINGS_ENUM_TEMPLATE_ID = 'settings.enum.template';
const SETTINGS_BOOL_TEMPLATE_ID = 'settings.bool.template';
const SETTINGS_ARRAY_TEMPLATE_ID = 'settings.array.template';
const SETTINGS_EXCLUDE_TEMPLATE_ID = 'settings.exclude.template';
const SETTINGS_COMPLEX_TEMPLATE_ID = 'settings.complex.template';
const SETTINGS_NEW_EXTENSIONS_TEMPLATE_ID = 'settings.newExtensions.template';
@@ -249,7 +264,7 @@ export interface ISettingOverrideClickEvent {
targetKey: string;
}
export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsTreeElement, never, any> {
export abstract class AbstractSettingRenderer extends Disposable implements ITreeRenderer<SettingsTreeElement, never, any> {
/** To override */
abstract get templateId(): string;
@@ -261,19 +276,19 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
static readonly SETTING_KEY_ATTR = 'data-key';
static readonly SETTING_ID_ATTR = 'data-id';
private readonly _onDidClickOverrideElement = new Emitter<ISettingOverrideClickEvent>();
private readonly _onDidClickOverrideElement = this._register(new Emitter<ISettingOverrideClickEvent>());
readonly onDidClickOverrideElement: Event<ISettingOverrideClickEvent> = this._onDidClickOverrideElement.event;
protected readonly _onDidChangeSetting = new Emitter<ISettingChangeEvent>();
protected readonly _onDidChangeSetting = this._register(new Emitter<ISettingChangeEvent>());
readonly onDidChangeSetting: Event<ISettingChangeEvent> = this._onDidChangeSetting.event;
protected readonly _onDidOpenSettings = new Emitter<string>();
protected readonly _onDidOpenSettings = this._register(new Emitter<string>());
readonly onDidOpenSettings: Event<string> = this._onDidOpenSettings.event;
private readonly _onDidClickSettingLink = new Emitter<ISettingLinkClickEvent>();
private readonly _onDidClickSettingLink = this._register(new Emitter<ISettingLinkClickEvent>());
readonly onDidClickSettingLink: Event<ISettingLinkClickEvent> = this._onDidClickSettingLink.event;
private readonly _onDidFocusSetting = new Emitter<SettingsTreeSettingElement>();
private readonly _onDidFocusSetting = this._register(new Emitter<SettingsTreeSettingElement>());
readonly onDidFocusSetting: Event<SettingsTreeSettingElement> = this._onDidFocusSetting.event;
// Put common injections back here
@@ -287,6 +302,7 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
@IContextMenuService protected readonly _contextMenuService: IContextMenuService,
@IKeybindingService protected readonly _keybindingService: IKeybindingService,
) {
super();
}
renderTemplate(container: HTMLElement): any {
@@ -401,7 +417,9 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
template.descriptionElement.innerHTML = '';
if (element.setting.descriptionIsMarkdown) {
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, template.toDispose);
const disposables = new DisposableStore();
template.toDispose.push(disposables);
const renderedDescription = this.renderDescriptionMarkdown(element, element.description, disposables);
template.descriptionElement.appendChild(renderedDescription);
} else {
template.descriptionElement.innerText = element.description;
@@ -445,7 +463,7 @@ export abstract class AbstractSettingRenderer implements ITreeRenderer<SettingsT
}
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: IDisposable[]): HTMLElement {
private renderDescriptionMarkdown(element: SettingsTreeSettingElement, text: string, disposeables: DisposableStore): HTMLElement {
// Rewrite `#editor.fontSize#` to link format
text = fixSettingLinks(text);
@@ -652,11 +670,81 @@ export class SettingComplexRenderer extends AbstractSettingRenderer implements I
}
}
export class SettingArrayRenderer extends AbstractSettingRenderer implements ITreeRenderer<SettingsTreeSettingElement, never, ISettingListItemTemplate> {
templateId = SETTINGS_ARRAY_TEMPLATE_ID;
renderTemplate(container: HTMLElement): ISettingListItemTemplate {
const common = this.renderCommonTemplate(null, container, 'list');
const listWidget = this._instantiationService.createInstance(ListSettingWidget, common.controlElement);
listWidget.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
common.toDispose.push(listWidget);
const template: ISettingListItemTemplate = {
...common,
listWidget
};
this.addSettingElementFocusHandler(template);
common.toDispose.push(listWidget.onDidChangeList(e => this.onDidChangeList(template, e)));
return template;
}
private onDidChangeList(template: ISettingListItemTemplate, e: IListChangeEvent): void {
if (template.context) {
const newValue: any[] | undefined = isArray(template.context.scopeValue)
? [...template.context.scopeValue]
: [...template.context.value];
// Delete value
if (e.removeIndex) {
if (!e.value && e.originalValue && e.removeIndex > -1) {
newValue.splice(e.removeIndex, 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;
}
// For some reason, we are updating and cannot find original value
// Just append the value in this case
else {
newValue.push(e.value);
}
}
this._onDidChangeSetting.fire({
key: template.context.setting.key,
value: newValue,
type: template.context.valueType
});
}
}
renderElement(element: ITreeNode<SettingsTreeSettingElement, never>, index: number, templateData: ISettingListItemTemplate): void {
super.renderSettingElement(element, index, templateData);
}
protected renderValue(dataElement: SettingsTreeSettingElement, template: ISettingListItemTemplate, onChange: (value: string) => void): void {
const value = getListDisplayValue(dataElement);
template.listWidget.setValue(value);
template.context = dataElement;
}
}
export class SettingExcludeRenderer extends AbstractSettingRenderer implements ITreeRenderer<SettingsTreeSettingElement, never, ISettingExcludeItemTemplate> {
templateId = SETTINGS_EXCLUDE_TEMPLATE_ID;
renderTemplate(container: HTMLElement): ISettingExcludeItemTemplate {
const common = this.renderCommonTemplate(null, container, 'exclude');
const common = this.renderCommonTemplate(null, container, 'list');
const excludeWidget = this._instantiationService.createInstance(ExcludeSettingWidget, common.controlElement);
excludeWidget.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
@@ -669,46 +757,45 @@ export class SettingExcludeRenderer extends AbstractSettingRenderer implements I
this.addSettingElementFocusHandler(template);
common.toDispose.push(excludeWidget.onDidChangeExclude(e => this.onDidChangeExclude(template, e)));
common.toDispose.push(excludeWidget.onDidChangeList(e => this.onDidChangeExclude(template, e)));
return template;
}
private onDidChangeExclude(template: ISettingExcludeItemTemplate, e: IExcludeChangeEvent): void {
private onDidChangeExclude(template: ISettingExcludeItemTemplate, e: IListChangeEvent): void {
if (template.context) {
const newValue = { ...template.context.scopeValue };
// first delete the existing entry, if present
if (e.originalPattern) {
if (e.originalPattern in template.context.defaultValue) {
if (e.originalValue) {
if (e.originalValue in template.context.defaultValue) {
// delete a default by overriding it
newValue[e.originalPattern] = false;
newValue[e.originalValue] = false;
} else {
delete newValue[e.originalPattern];
delete newValue[e.originalValue];
}
}
// then add the new or updated entry, if present
if (e.pattern) {
if (e.pattern in template.context.defaultValue && !e.sibling) {
if (e.value) {
if (e.value in template.context.defaultValue && !e.sibling) {
// add a default by deleting its override
delete newValue[e.pattern];
delete newValue[e.value];
} else {
newValue[e.pattern] = e.sibling ? { when: e.sibling } : true;
newValue[e.value] = e.sibling ? { when: e.sibling } : true;
}
}
const sortKeys = (obj: Object) => {
const keyArray = Object.keys(obj)
.map(key => ({ key, val: obj[key] }))
.sort((a, b) => a.key.localeCompare(b.key));
function sortKeys<T extends object>(obj: T) {
const sortedKeys = Object.keys(obj)
.sort((a, b) => a.localeCompare(b)) as Array<keyof T>;
const retVal = {};
keyArray.forEach(pair => {
retVal[pair.key] = pair.val;
});
const retVal: Partial<T> = {};
for (const key of sortedKeys) {
retVal[key] = obj[key];
}
return retVal;
};
}
this._onDidChangeSetting.fire({
key: template.context.setting.key,
@@ -939,11 +1026,11 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
const deprecationWarningElement = DOM.append(container, $('.setting-item-deprecation-message'));
const toDispose: IDisposable[] = [];
const toDispose = new DisposableStore();
const checkbox = new Checkbox({ actionClassName: 'setting-value-checkbox', isChecked: true, title: '', inputActiveOptionBorder: undefined });
controlElement.appendChild(checkbox.domNode);
toDispose.push(checkbox);
toDispose.push(checkbox.onChange(() => {
toDispose.add(checkbox);
toDispose.add(checkbox.onChange(() => {
if (template.onChange) {
template.onChange(checkbox.checked);
}
@@ -951,7 +1038,7 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
// Need to listen for mouse clicks on description and toggle checkbox - use target ID for safety
// Also have to ignore embedded links - too buried to stop propagation
toDispose.push(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => {
toDispose.add(DOM.addDisposableListener(descriptionElement, DOM.EventType.MOUSE_DOWN, (e) => {
const targetElement = <HTMLElement>e.target;
const targetId = descriptionElement.getAttribute('checkbox_label_target_id');
@@ -968,10 +1055,10 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
checkbox.domNode.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
const toolbarContainer = DOM.append(container, $('.setting-toolbar-container'));
const toolbar = this.renderSettingToolbar(toolbarContainer);
toDispose.push(toolbar);
toDispose.add(toolbar);
const template: ISettingBoolItemTemplate = {
toDispose,
toDispose: [toDispose],
containerElement: container,
categoryElement,
@@ -987,16 +1074,16 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
this.addSettingElementFocusHandler(template);
// Prevent clicks from being handled by list
toDispose.push(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation()));
toDispose.add(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation()));
toDispose.push(DOM.addStandardDisposableListener(controlElement, 'keydown', (e: StandardKeyboardEvent) => {
toDispose.add(DOM.addStandardDisposableListener(controlElement, 'keydown', (e: StandardKeyboardEvent) => {
if (e.keyCode === KeyCode.Escape) {
e.browserEvent.stopPropagation();
}
}));
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_ENTER, e => container.classList.add('mouseover')));
toDispose.push(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_LEAVE, e => container.classList.remove('mouseover')));
toDispose.add(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_ENTER, e => container.classList.add('mouseover')));
toDispose.add(DOM.addDisposableListener(titleElement, DOM.EventType.MOUSE_LEAVE, e => container.classList.remove('mouseover')));
return template;
}
@@ -1053,6 +1140,7 @@ export class SettingTreeRenderers {
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions),
this._instantiationService.createInstance(SettingNumberRenderer, this.settingActions),
this._instantiationService.createInstance(SettingBoolRenderer, this.settingActions),
this._instantiationService.createInstance(SettingArrayRenderer, this.settingActions),
this._instantiationService.createInstance(SettingComplexRenderer, this.settingActions),
this._instantiationService.createInstance(SettingTextRenderer, this.settingActions),
this._instantiationService.createInstance(SettingExcludeRenderer, this.settingActions),
@@ -1163,6 +1251,7 @@ function escapeInvisibleChars(enumValue: string): string {
export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
constructor(
private viewState: ISettingsEditorViewState,
@IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService,
) { }
filter(element: SettingsTreeElement, parentVisibility: TreeVisibility): TreeFilterResult<void> {
@@ -1175,7 +1264,8 @@ export class SettingsTreeFilter implements ITreeFilter<SettingsTreeElement> {
// Non-user scope selected
if (element instanceof SettingsTreeSettingElement && this.viewState.settingsTarget !== ConfigurationTarget.USER_LOCAL) {
if (!element.matchesScope(this.viewState.settingsTarget)) {
const isRemote = !!this.environmentService.configuration.remoteAuthority;
if (!element.matchesScope(this.viewState.settingsTarget, isRemote)) {
return false;
}
}
@@ -1249,23 +1339,27 @@ class SettingsTreeDelegate implements IListVirtualDelegate<SettingsTreeGroupChil
}
if (element instanceof SettingsTreeSettingElement) {
if (element.valueType === 'boolean') {
if (element.valueType === SettingValueType.Boolean) {
return SETTINGS_BOOL_TEMPLATE_ID;
}
if (element.valueType === 'integer' || element.valueType === 'number' || element.valueType === 'nullable-integer' || element.valueType === 'nullable-number') {
if (element.valueType === SettingValueType.Integer || element.valueType === SettingValueType.Number || element.valueType === SettingValueType.NullableInteger || element.valueType === SettingValueType.NullableNumber) {
return SETTINGS_NUMBER_TEMPLATE_ID;
}
if (element.valueType === 'string') {
if (element.valueType === SettingValueType.String) {
return SETTINGS_TEXT_TEMPLATE_ID;
}
if (element.valueType === 'enum') {
if (element.valueType === SettingValueType.Enum) {
return SETTINGS_ENUM_TEMPLATE_ID;
}
if (element.valueType === 'exclude') {
if (element.valueType === SettingValueType.ArrayOfString) {
return SETTINGS_ARRAY_TEMPLATE_ID;
}
if (element.valueType === SettingValueType.Exclude) {
return SETTINGS_EXCLUDE_TEMPLATE_ID;
}
@@ -1303,7 +1397,8 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
container: HTMLElement,
viewState: ISettingsEditorViewState,
renderers: ITreeRenderer<any, void, any>[],
@IThemeService themeService: IThemeService
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
) {
const treeClass = 'settings-editor-tree';
@@ -1320,7 +1415,7 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
}
},
styleController: new DefaultStyleController(DOM.createStyleSheet(container), treeClass),
filter: new SettingsTreeFilter(viewState)
filter: instantiationService.createInstance(SettingsTreeFilter, viewState)
});
this.disposables = [];
@@ -1409,9 +1504,9 @@ class CopySettingIdAction extends Action {
super(CopySettingIdAction.ID, CopySettingIdAction.LABEL);
}
run(context: SettingsTreeSettingElement): Promise<void> {
async run(context: SettingsTreeSettingElement): Promise<void> {
if (context) {
this.clipboardService.writeText(context.setting.key);
await this.clipboardService.writeText(context.setting.key);
}
return Promise.resolve(undefined);
@@ -1428,10 +1523,10 @@ class CopySettingAsJSONAction extends Action {
super(CopySettingAsJSONAction.ID, CopySettingAsJSONAction.LABEL);
}
run(context: SettingsTreeSettingElement): Promise<void> {
async run(context: SettingsTreeSettingElement): Promise<void> {
if (context) {
const jsonResult = `"${context.setting.key}": ${JSON.stringify(context.value, undefined, ' ')}`;
this.clipboardService.writeText(jsonResult);
await this.clipboardService.writeText(jsonResult);
}
return Promise.resolve(undefined);