提交 6527a512 编写于 作者: R Rob Lourens

Revert "Merge branch 'roblou/revertSettingsEditorChanges'"

This reverts commit 3c448ca5, reversing
changes made to 8ce1c41c.
上级 6b083b45
......@@ -175,14 +175,14 @@
.settings-editor > .settings-body .settings-tree-container .setting-toolbar-container {
position: absolute;
left: -32px;
left: -22px;
top: 11px;
bottom: 0px;
width: 26px;
}
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .mouseover .setting-toolbar-container > .monaco-toolbar .codicon,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-item-contents.focused .setting-toolbar-container > .monaco-toolbar .codicon,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row.focused .setting-item-contents .setting-toolbar-container > .monaco-toolbar .codicon,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container:hover > .monaco-toolbar .codicon,
.settings-editor > .settings-body .settings-tree-container .monaco-list-row .setting-toolbar-container > .monaco-toolbar .active .codicon {
opacity: 1;
......@@ -283,15 +283,34 @@
max-width: 1000px;
margin: auto;
box-sizing: border-box;
padding-left: 219px;
padding-right: 20px;
padding-left: 204px;
padding-right: 5px;
overflow: visible;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::before,
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::after,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::before,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::after {
content: ' ';
position: absolute;
left: 0px;
right: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::before,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::before {
top: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label::after,
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents::after {
bottom: 0px;
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents {
position: relative;
padding-top: 12px;
padding-bottom: 18px;
padding: 12px 15px 18px;
white-space: normal;
}
......@@ -299,11 +318,9 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
/* size to contents for hover to show context button */
display: inline-block; /* size to contents for hover to show context button */
}
.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-modified-indicator {
display: none;
}
......@@ -315,7 +332,7 @@
width: 6px;
border-left-width: 2px;
border-left-style: solid;
left: -9px;
left: 5px;
top: 15px;
bottom: 16px;
}
......@@ -528,12 +545,18 @@
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label {
display: inline-block;
margin: 0px;
font-weight: 600;
height: 100%;
box-sizing: border-box;
padding: 10px;
padding-left: 15px;
width: 100%;
position: relative;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-1 {
padding-top: 23px;
font-size: 24px;
}
......@@ -542,10 +565,6 @@
font-size: 20px;
}
.settings-editor > .settings-body > .settings-tree-container .settings-group-level-1.settings-group-first {
padding-top: 7px;
}
.settings-editor.search-mode > .settings-body .settings-toc-container .monaco-list-row .settings-toc-count {
display: block;
}
......@@ -12,7 +12,7 @@ import * as nls from 'vs/nls';
import { Action2, MenuId, MenuRegistry, registerAction2 } from 'vs/platform/actions/common/actions';
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
import { IsMacNativeContext } from 'vs/platform/contextkey/common/contextkeys';
import { InputFocusedContext, IsMacNativeContext } from 'vs/platform/contextkey/common/contextkeys';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
......@@ -40,6 +40,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
import { DefaultPreferencesEditorInput, KeybindingsEditorInput, PreferencesEditorInput, SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput';
import { AbstractSideBySideEditorInputFactory } from 'vs/workbench/browser/parts/editor/editor.contribution';
import { WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService';
const SETTINGS_EDITOR_COMMAND_SEARCH = 'settings.action.search';
......@@ -50,6 +51,8 @@ const SETTINGS_EDITOR_COMMAND_EDIT_FOCUSED_SETTING = 'settings.action.editFocuse
const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_FROM_SEARCH = 'settings.action.focusSettingsFromSearch';
const SETTINGS_EDITOR_COMMAND_FOCUS_SETTINGS_LIST = 'settings.action.focusSettingsList';
const SETTINGS_EDITOR_COMMAND_FOCUS_TOC = 'settings.action.focusTOC';
const SETTINGS_EDITOR_COMMAND_FOCUS_TOC2 = 'settings.action.focusTOC2';
const SETTINGS_EDITOR_COMMAND_FOCUS_CONTROL = 'settings.action.focusSettingControl';
const SETTINGS_EDITOR_COMMAND_SWITCH_TO_JSON = 'settings.switchToJSON';
const SETTINGS_EDITOR_COMMAND_FILTER_MODIFIED = 'settings.filterByModified';
......@@ -507,6 +510,14 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
}
return null;
}
function settingsEditorFocusSearch(accessor: ServicesAccessor) {
const preferencesEditor = getPreferencesEditor(accessor);
if (preferencesEditor) {
preferencesEditor.focusSearch();
}
}
registerAction2(class extends Action2 {
constructor() {
super({
......@@ -521,12 +532,24 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
});
}
run(accessor: ServicesAccessor) {
const preferencesEditor = getPreferencesEditor(accessor);
if (preferencesEditor) {
preferencesEditor.focusSearch();
}
run(accessor: ServicesAccessor) { settingsEditorFocusSearch(accessor); }
});
registerAction2(class extends Action2 {
constructor() {
super({
id: SETTINGS_EDITOR_COMMAND_SEARCH,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS),
keybinding: {
primary: KeyCode.Escape,
weight: KeybindingWeight.WorkbenchContrib,
when: null
},
title: nls.localize('settings.focusSearch', "Focus settings search")
});
}
run(accessor: ServicesAccessor) { settingsEditorFocusSearch(accessor); }
});
registerAction2(class extends Action2 {
......@@ -691,19 +714,79 @@ class PreferencesActionsContribution extends Disposable implements IWorkbenchCon
constructor() {
super({
id: SETTINGS_EDITOR_COMMAND_FOCUS_TOC,
precondition: CONTEXT_SETTINGS_EDITOR,
keybinding: [
{
primary: KeyCode.Escape,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate()),
},
{
primary: KeyCode.LeftArrow,
weight: KeybindingWeight.WorkbenchContrib,
when: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate(), InputFocusedContext.negate())
}],
title: nls.localize('settings.focusSettingsTOC', "Focus settings TOC tree")
});
}
run(accessor: ServicesAccessor): void {
const preferencesEditor = getPreferencesEditor(accessor);
if (preferencesEditor instanceof SettingsEditor2) {
if (!(preferencesEditor instanceof SettingsEditor2)) {
return;
}
if (document.activeElement?.classList.contains('monaco-list')) {
preferencesEditor.focusTOC();
} else {
preferencesEditor.focusSettings();
}
}
});
registerAction2(class extends Action2 {
constructor() {
super({
id: SETTINGS_EDITOR_COMMAND_FOCUS_CONTROL,
precondition: ContextKeyExpr.and(CONTEXT_SETTINGS_EDITOR, CONTEXT_TOC_ROW_FOCUS.negate(), WorkbenchListFocusContextKey),
keybinding: {
primary: KeyCode.Enter,
weight: KeybindingWeight.WorkbenchContrib,
},
title: nls.localize('settings.focusSettingControl', "Focus setting control")
});
}
run(accessor: ServicesAccessor): void {
const preferencesEditor = getPreferencesEditor(accessor);
if (!(preferencesEditor instanceof SettingsEditor2)) {
return;
}
if (document.activeElement?.classList.contains('monaco-list')) {
preferencesEditor.focusSettings(true);
}
}
});
registerAction2(class extends Action2 {
constructor() {
super({
id: SETTINGS_EDITOR_COMMAND_FOCUS_TOC2,
title: nls.localize('settings.focusSettingsTOC', "Focus settings TOC tree")
});
}
run(accessor: ServicesAccessor): void {
const preferencesEditor = getPreferencesEditor(accessor);
if (!(preferencesEditor instanceof SettingsEditor2)) {
return;
}
preferencesEditor.focusTOC();
}
});
registerAction2(class extends Action2 {
constructor() {
super({
......
......@@ -43,7 +43,7 @@ import { IEditorMemento, IEditorOpenContext, IEditorPane } from 'vs/workbench/co
import { attachSuggestEnabledInputBoxStyler, SuggestEnabledInput } from 'vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput';
import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets';
import { commonlyUsedData, tocData } from 'vs/workbench/contrib/preferences/browser/settingsLayout';
import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickEvent, resolveExtensionsSettings, resolveSettingsTree, SettingsTree, SettingTreeRenderers } from 'vs/workbench/contrib/preferences/browser/settingsTree';
import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickEvent, resolveExtensionsSettings, resolveSettingsTree, SettingsTree, SettingTreeRenderers, updateSettingTreeTabOrder } from 'vs/workbench/contrib/preferences/browser/settingsTree';
import { ISettingsEditorViewState, parseQuery, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels';
import { settingsTextInputBorder } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { createTOCIterator, TOCTree, TOCTreeModel } from 'vs/workbench/contrib/preferences/browser/tocTree';
......@@ -149,6 +149,7 @@ export class SettingsEditor2 extends EditorPane {
private editorMemento: IEditorMemento<ISettingsEditor2State>;
private tocFocusedElement: SettingsTreeGroupElement | null = null;
private treeFocusedElement: SettingsTreeElement | null = null;
private settingsTreeScrollTop = 0;
private dimension!: DOM.Dimension;
......@@ -349,7 +350,8 @@ export class SettingsEditor2 extends EditorPane {
}
}
focusSettings(): void {
focusSettings(focusSettingInput = false): void {
// TODO@roblourens is this in the right place?
// Update ARIA global labels
const labelElement = this.settingsAriaExtraLabelsContainer.querySelector('#settings_aria_more_actions_shortcut_label');
if (labelElement) {
......@@ -359,9 +361,18 @@ export class SettingsEditor2 extends EditorPane {
}
}
const firstFocusable = this.settingsTree.getHTMLElement().querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
if (firstFocusable) {
(<HTMLElement>firstFocusable).focus();
const focused = this.settingsTree.getFocus();
if (!focused.length) {
this.settingsTree.focusFirst();
}
this.settingsTree.domFocus();
if (focusSettingInput) {
const controlInFocusedRow = this.settingsTree.getHTMLElement().querySelector(`.focused ${AbstractSettingRenderer.CONTROL_SELECTOR}`);
if (controlInFocusedRow) {
(<HTMLElement>controlInFocusedRow).focus();
}
}
}
......@@ -511,6 +522,11 @@ export class SettingsEditor2 extends EditorPane {
this.settingsTree.reveal(elements[0], sourceTop);
// We need to shift focus from the setting that contains the link to the setting that's
// linked. Clicking on the link sets focus on the setting that contains the link,
// which is why we need the setTimeout
setTimeout(() => this.settingsTree.setFocus([elements[0]]), 50);
const domElements = this.settingRenderers.getDOMElementsForSettingKey(this.settingsTree.getHTMLElement(), evt.targetKey);
if (domElements && domElements[0]) {
const control = domElements[0].querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
......@@ -571,48 +587,7 @@ export class SettingsEditor2 extends EditorPane {
}));
this.createTOC(bodyContainer);
this.createFocusSink(
bodyContainer,
e => {
if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) {
if (this.settingsTree.scrollTop > 0) {
const firstElement = this.settingsTree.firstVisibleElement;
if (typeof firstElement !== 'undefined') {
this.settingsTree.reveal(firstElement, 0.1);
}
return true;
}
} else {
const firstControl = this.settingsTree.getHTMLElement().querySelector(AbstractSettingRenderer.CONTROL_SELECTOR);
if (firstControl) {
(<HTMLElement>firstControl).focus();
}
}
return false;
},
'settings list focus helper');
this.createSettingsTree(bodyContainer);
this.createFocusSink(
bodyContainer,
e => {
if (DOM.findParentWithClass(e.relatedTarget, 'settings-editor-tree')) {
if (this.settingsTree.scrollTop < this.settingsTree.scrollHeight) {
const lastElement = this.settingsTree.lastVisibleElement;
this.settingsTree.reveal(lastElement, 0.9);
return true;
}
}
return false;
},
'settings list focus helper'
);
}
private addCtrlAInterceptor(container: HTMLElement): void {
......@@ -630,19 +605,6 @@ export class SettingsEditor2 extends EditorPane {
}));
}
private createFocusSink(container: HTMLElement, callback: (e: any) => boolean, label: string): HTMLElement {
const listFocusSink = DOM.append(container, $('.settings-tree-focus-sink'));
listFocusSink.setAttribute('aria-label', label);
listFocusSink.tabIndex = 0;
this._register(DOM.addDisposableListener(listFocusSink, 'focus', (e: any) => {
if (e.relatedTarget && callback(e)) {
e.relatedTarget.focus();
}
}));
return listFocusSink;
}
private createTOC(parent: HTMLElement): void {
this.tocTreeModel = this.instantiationService.createInstance(TOCTreeModel, this.viewState);
this.tocTreeContainer = DOM.append(parent, $('.settings-toc-container'));
......@@ -670,6 +632,7 @@ export class SettingsEditor2 extends EditorPane {
}
} else if (element && (!e.browserEvent || !(<IFocusEventFromScroll>e.browserEvent).fromScroll)) {
this.settingsTree.reveal(element, 0);
this.settingsTree.setFocus([element]);
}
}));
......@@ -719,7 +682,6 @@ export class SettingsEditor2 extends EditorPane {
this.settingsTreeContainer,
this.viewState,
this.settingRenderers.allRenderers));
this.settingsTree.getHTMLElement().attributes.removeNamedItem('tabindex');
this._register(this.settingsTree.onDidScroll(() => {
if (this.settingsTree.scrollTop === this.settingsTreeScrollTop) {
......@@ -727,6 +689,7 @@ export class SettingsEditor2 extends EditorPane {
}
this.settingsTreeScrollTop = this.settingsTree.scrollTop;
updateSettingTreeTabOrder(this.settingsTreeContainer);
// setTimeout because calling setChildren on the settingsTree can trigger onDidScroll, so it fires when
// setChildren has called on the settings tree but not the toc tree yet, so their rendered elements are out of sync
......@@ -734,6 +697,20 @@ export class SettingsEditor2 extends EditorPane {
this.updateTreeScrollSync();
}, 0);
}));
// There is no different select state in the settings tree
this._register(this.settingsTree.onDidChangeFocus(e => {
const element = e.elements[0];
if (this.treeFocusedElement === element) {
return;
}
this.treeFocusedElement = element;
this.settingsTree.setSelection(element ? [element] : []);
// Wait for rendering to complete
setTimeout(() => updateSettingTreeTabOrder(this.settingsTreeContainer), 0);
}));
}
private notifyNoSaveNeeded() {
......
......@@ -5,7 +5,6 @@
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import * as DOM from 'vs/base/browser/dom';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { alert as ariaAlert } from 'vs/base/browser/ui/aria/aria';
......@@ -16,7 +15,7 @@ import { CachedListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { DefaultStyleController } from 'vs/base/browser/ui/list/listWidget';
import { ISelectOptionItem, SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { ToolBar } from 'vs/base/browser/ui/toolbar/toolbar';
import { IObjectTreeOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { IObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
import { ObjectTreeModel } from 'vs/base/browser/ui/tree/objectTreeModel';
import { ITreeFilter, ITreeModel, ITreeNode, ITreeRenderer, TreeFilterResult, TreeVisibility } from 'vs/base/browser/ui/tree/tree';
import { Action, IAction, Separator } from 'vs/base/common/actions';
......@@ -43,7 +42,7 @@ import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticip
import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge';
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, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsHeaderForeground, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester, focusedRowBackground, focusedRowBorder, settingsHeaderForeground, rowHoverBackground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { ISetting, ISettingsGroup, SettingValueType } from 'vs/workbench/services/preferences/common/preferences';
......@@ -53,6 +52,9 @@ import { Codicon } from 'vs/base/common/codicons';
import { CodiconLabel } from 'vs/base/browser/ui/codicons/codiconLabel';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
import { IList } from 'vs/base/browser/ui/tree/indexTreeModel';
import { IListService, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
const $ = DOM.$;
......@@ -451,6 +453,45 @@ export interface ISettingOverrideClickEvent {
targetKey: string;
}
function removeChildrenFromTabOrder(node: Element): void {
const focusableElements = node.querySelectorAll(`
[tabindex="0"],
input:not([tabindex="-1"]),
select:not([tabindex="-1"]),
textarea:not([tabindex="-1"]),
a:not([tabindex="-1"]),
button:not([tabindex="-1"]),
area:not([tabindex="-1"])
`);
focusableElements.forEach(element => {
element.setAttribute(AbstractSettingRenderer.ELEMENT_FOCUSABLE_ATTR, 'true');
element.setAttribute('tabindex', '-1');
});
}
function addChildrenToTabOrder(node: Element): void {
const focusableElements = node.querySelectorAll(
`[${AbstractSettingRenderer.ELEMENT_FOCUSABLE_ATTR}="true"]`
);
focusableElements.forEach(element => {
element.removeAttribute(AbstractSettingRenderer.ELEMENT_FOCUSABLE_ATTR);
element.setAttribute('tabindex', '0');
});
}
export function updateSettingTreeTabOrder(container: Element): void {
const allRows = [...container.querySelectorAll(AbstractSettingRenderer.ALL_ROWS_SELECTOR)];
const focusedRow = allRows.find(row => row.classList.contains('focused'));
allRows.forEach(removeChildrenFromTabOrder);
if (isDefined(focusedRow)) {
addChildrenToTabOrder(focusedRow);
}
}
export abstract class AbstractSettingRenderer extends Disposable implements ITreeRenderer<SettingsTreeElement, never, any> {
/** To override */
abstract get templateId(): string;
......@@ -459,9 +500,11 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
static readonly CONTROL_SELECTOR = '.' + AbstractSettingRenderer.CONTROL_CLASS;
static readonly CONTENTS_CLASS = 'setting-item-contents';
static readonly CONTENTS_SELECTOR = '.' + AbstractSettingRenderer.CONTENTS_CLASS;
static readonly ALL_ROWS_SELECTOR = '.monaco-list-row';
static readonly SETTING_KEY_ATTR = 'data-key';
static readonly SETTING_ID_ATTR = 'data-id';
static readonly ELEMENT_FOCUSABLE_ATTR = 'data-focusable';
private readonly _onDidClickOverrideElement = this._register(new Emitter<ISettingOverrideClickEvent>());
readonly onDidClickOverrideElement: Event<ISettingOverrideClickEvent> = this._onDidClickOverrideElement.event;
......@@ -607,7 +650,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
private fixToolbarIcon(toolbar: ToolBar): void {
const button = toolbar.getElement().querySelector('.codicon-toolbar-more');
if (button) {
(<HTMLElement>button).tabIndex = -1;
(<HTMLElement>button).tabIndex = 0;
// change icon from ellipsis to gear
(<HTMLElement>button).classList.add('codicon-gear');
......@@ -1248,6 +1291,15 @@ export class SettingTextRenderer extends AbstractSettingRenderer implements ITre
}));
common.toDispose.add(inputBox);
inputBox.inputElement.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
inputBox.inputElement.tabIndex = 0;
// TODO@9at8: listWidget filters out all key events from input boxes, so we need to come up with a better way
// Disable ArrowUp and ArrowDown behaviour in favor of list navigation
common.toDispose.add(DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, e => {
if (e.equals(KeyCode.UpArrow) || e.equals(KeyCode.DownArrow)) {
e.preventDefault();
}
}));
const template: ISettingTextItemTemplate = {
...common,
......@@ -1300,6 +1352,7 @@ export class SettingEnumRenderer extends AbstractSettingRenderer implements ITre
const selectElement = common.controlElement.querySelector('select');
if (selectElement) {
selectElement.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
selectElement.tabIndex = 0;
}
common.toDispose.add(
......@@ -1392,6 +1445,7 @@ export class SettingNumberRenderer extends AbstractSettingRenderer implements IT
}));
common.toDispose.add(inputBox);
inputBox.inputElement.classList.add(AbstractSettingRenderer.CONTROL_CLASS);
inputBox.inputElement.tabIndex = 0;
const template: ISettingNumberItemTemplate = {
...common,
......@@ -1504,13 +1558,6 @@ export class SettingBoolRenderer extends AbstractSettingRenderer implements ITre
// Prevent clicks from being handled by list
toDispose.add(DOM.addDisposableListener(controlElement, 'mousedown', (e: IMouseEvent) => e.stopPropagation()));
toDispose.add(DOM.addStandardDisposableListener(controlElement, 'keydown', (e: StandardKeyboardEvent) => {
if (e.keyCode === KeyCode.Escape) {
e.browserEvent.stopPropagation();
}
}));
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')));
......@@ -1834,11 +1881,7 @@ class SettingsTreeDelegate extends CachedListVirtualDelegate<SettingsTreeGroupCh
protected estimateHeight(element: SettingsTreeGroupChild): number {
if (element instanceof SettingsTreeGroupElement) {
if (element.isFirstGroup) {
return 31;
}
return 40 + (7 * element.level);
return 42;
}
return element instanceof SettingsTreeSettingElement && element.valueType === SettingValueType.Boolean ? 78 : 104;
......@@ -1855,19 +1898,24 @@ class NonCollapsibleObjectTreeModel<T> extends ObjectTreeModel<T> {
}
}
export class SettingsTree extends ObjectTree<SettingsTreeElement> {
export class SettingsTree extends WorkbenchObjectTree<SettingsTreeElement> {
constructor(
container: HTMLElement,
viewState: ISettingsEditorViewState,
renderers: ITreeRenderer<any, void, any>[],
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService keybindingService: IKeybindingService,
@IAccessibilityService accessibilityService: IAccessibilityService,
@IInstantiationService instantiationService: IInstantiationService,
) {
super('SettingsTree', container,
new SettingsTreeDelegate(),
renderers,
{
horizontalScrolling: false,
supportDynamicHeights: true,
identityProvider: {
getId(e) {
......@@ -1875,9 +1923,6 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
}
},
accessibilityProvider: {
getWidgetRole() {
return 'form';
},
getAriaLabel() {
// TODO@roblourens https://github.com/microsoft/vscode/issues/95862
return '';
......@@ -1889,9 +1934,16 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
styleController: id => new DefaultStyleController(DOM.createStyleSheet(container), id),
filter: instantiationService.createInstance(SettingsTreeFilter, viewState),
smoothScrolling: configurationService.getValue<boolean>('workbench.list.smoothScrolling'),
});
multipleSelectionSupport: false,
},
contextKeyService,
listService,
themeService,
configurationService,
keybindingService,
accessibilityService,
);
this.disposables.clear();
this.disposables.add(registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const activeBorderColor = theme.getColor(focusBorder);
if (activeBorderColor) {
......@@ -1930,6 +1982,26 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.invalid-input .setting-item-control .monaco-inputbox.idle { outline-width: 0; border-style:solid; border-width: 1px; border-color: ${invalidInputBorder}; }`);
}
const focusedRowBackgroundColor = theme.getColor(focusedRowBackground);
if (focusedRowBackgroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.focused .setting-item-contents,
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.focused .settings-group-title-label { background-color: ${focusedRowBackgroundColor}; }`);
}
const rowHoverBackgroundColor = theme.getColor(rowHoverBackground);
if (rowHoverBackgroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row .setting-item-contents:hover,
.settings-editor > .settings-body > .settings-tree-container .monaco-list-row .settings-group-title-label:hover { background-color: ${rowHoverBackgroundColor}; }`);
}
const focusedRowBorderColor = theme.getColor(focusedRowBorder);
if (focusedRowBorderColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .setting-item-contents::before,
.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .setting-item-contents::after { border-top: 1px solid ${focusedRowBorderColor} }`);
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .settings-group-title-label::before,
.settings-editor > .settings-body > .settings-tree-container .monaco-list:focus-within .monaco-list-row.focused .settings-group-title-label::after { border-top: 1px solid ${focusedRowBorderColor} }`);
}
const headerForegroundColor = theme.getColor(settingsHeaderForeground);
if (headerForegroundColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .settings-group-title-label { color: ${headerForegroundColor}; }`);
......@@ -1940,6 +2012,12 @@ export class SettingsTree extends ObjectTree<SettingsTreeElement> {
if (focusBorderColor) {
collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-markdown a:focus { outline-color: ${focusBorderColor} }`);
}
// const listActiveSelectionBackgroundColor = theme.getColor(listActiveSelectionBackground);
// if (listActiveSelectionBackgroundColor) {
// collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .setting-item-contents .setting-item-title { background-color: ${listActiveSelectionBackgroundColor}; }`);
// collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .monaco-list-row.selected .settings-group-title-label { background-color: ${listActiveSelectionBackgroundColor}; }`);
// }
}));
this.getHTMLElement().classList.add('settings-editor-tree');
......
......@@ -16,7 +16,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import 'vs/css!./media/settingsWidgets';
import { localize } from 'vs/nls';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { foreground, inputBackground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground, simpleCheckboxBackground, simpleCheckboxForeground, simpleCheckboxBorder } from 'vs/platform/theme/common/colorRegistry';
import { foreground, inputBorder, inputForeground, listActiveSelectionBackground, listActiveSelectionForeground, listHoverBackground, listHoverForeground, listInactiveSelectionBackground, listInactiveSelectionForeground, registerColor, selectBackground, selectBorder, selectForeground, textLinkForeground, textPreformatForeground, editorWidgetBorder, textLinkActiveForeground, simpleCheckboxBackground, simpleCheckboxForeground, simpleCheckboxBorder, listFocusBackground, transparent, focusBorder } from 'vs/platform/theme/common/colorRegistry';
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { disposableTimeout } from 'vs/base/common/async';
......@@ -25,6 +25,7 @@ import { preferencesEditIcon } from 'vs/workbench/contrib/preferences/browser/pr
import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox';
import { isIOS } from 'vs/base/common/platform';
import { BrowserFeatures } from 'vs/base/browser/canIUse';
import { PANEL_BORDER } from 'vs/workbench/common/theme';
const $ = DOM.$;
export const settingsHeaderForeground = registerColor('settings.headerForeground', { light: '#444444', dark: '#e7e7e7', hc: '#ffffff' }, localize('headerForeground', "The foreground color for a section header or active title."));
......@@ -46,15 +47,33 @@ export const settingsCheckboxForeground = registerColor('settings.checkboxForegr
export const settingsCheckboxBorder = registerColor('settings.checkboxBorder', { dark: simpleCheckboxBorder, light: simpleCheckboxBorder, hc: simpleCheckboxBorder }, localize('settingsCheckboxBorder', "Settings editor checkbox border."));
// Text control colors
export const settingsTextInputBackground = registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "Settings editor text input box background."));
export const settingsTextInputBackground = settingsSelectBackground; //registerColor('settings.textInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('textInputBoxBackground', "Settings editor text input box background."));
export const settingsTextInputForeground = registerColor('settings.textInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('textInputBoxForeground', "Settings editor text input box foreground."));
export const settingsTextInputBorder = registerColor('settings.textInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('textInputBoxBorder', "Settings editor text input box border."));
// Number control colors
export const settingsNumberInputBackground = registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "Settings editor number input box background."));
export const settingsNumberInputBackground = settingsSelectBackground; // registerColor('settings.numberInputBackground', { dark: inputBackground, light: inputBackground, hc: inputBackground }, localize('numberInputBoxBackground', "Settings editor number input box background."));
export const settingsNumberInputForeground = registerColor('settings.numberInputForeground', { dark: inputForeground, light: inputForeground, hc: inputForeground }, localize('numberInputBoxForeground', "Settings editor number input box foreground."));
export const settingsNumberInputBorder = registerColor('settings.numberInputBorder', { dark: inputBorder, light: inputBorder, hc: inputBorder }, localize('numberInputBoxBorder', "Settings editor number input box border."));
export const focusedRowBackground = registerColor('settings.focusedRowBackground', {
dark: transparent(PANEL_BORDER, .4),
light: transparent(listFocusBackground, .4),
hc: null
}, localize('focusedRowBackground', "The background color of a cell when the row is focused."));
export const rowHoverBackground = registerColor('notebook.rowHoverBackground', {
dark: transparent(focusedRowBackground, .5),
light: transparent(focusedRowBackground, .7),
hc: null
}, localize('notebook.rowHoverBackground', "The background color of a row when the row is hovered."));
export const focusedRowBorder = registerColor('notebook.focusedRowBorder', {
dark: Color.white.transparent(0.12),
light: Color.black.transparent(0.12),
hc: focusBorder
}, localize('notebook.focusedRowBorder', "The color of the row's top and bottom border when the row is focused."));
registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) => {
const checkboxBackgroundColor = theme.getColor(settingsCheckboxBackground);
if (checkboxBackgroundColor) {
......@@ -527,7 +546,7 @@ export class ListSettingWidget extends AbstractListSettingWidget<IListDataItem>
valueInput.element.classList.add('setting-list-valueInput');
this.listDisposables.add(attachInputBoxStyler(valueInput, this.themeService, {
inputBackground: settingsTextInputBackground,
inputBackground: settingsSelectBackground,
inputForeground: settingsTextInputForeground,
inputBorder: settingsTextInputBorder
}));
......@@ -546,7 +565,7 @@ export class ListSettingWidget extends AbstractListSettingWidget<IListDataItem>
siblingInput.element.classList.add('setting-list-siblingInput');
this.listDisposables.add(siblingInput);
this.listDisposables.add(attachInputBoxStyler(siblingInput, this.themeService, {
inputBackground: settingsTextInputBackground,
inputBackground: settingsSelectBackground,
inputForeground: settingsTextInputForeground,
inputBorder: settingsTextInputBorder
}));
......@@ -908,7 +927,7 @@ export class ObjectSettingWidget extends AbstractListSettingWidget<IObjectDataIt
inputBox.element.classList.add('setting-list-object-input');
this.listDisposables.add(attachInputBoxStyler(inputBox, this.themeService, {
inputBackground: settingsTextInputBackground,
inputBackground: settingsSelectBackground,
inputForeground: settingsTextInputForeground,
inputBorder: settingsTextInputBorder
}));
......
......@@ -6,7 +6,6 @@
import * as DOM from 'vs/base/browser/dom';
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
import { DefaultStyleController, IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { IObjectTreeOptions, ObjectTree } from 'vs/base/browser/ui/tree/objectTree';
import { ITreeElement, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
import { Iterable } from 'vs/base/common/iterator';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -18,6 +17,11 @@ import { ISettingsEditorViewState, SearchResultModel, SettingsTreeElement, Setti
import { settingsHeaderForeground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets';
import { localize } from 'vs/nls';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IListService, IWorkbenchObjectTreeOptions, WorkbenchObjectTree } from 'vs/platform/list/browser/listService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
const $ = DOM.$;
......@@ -187,17 +191,22 @@ class SettingsAccessibilityProvider implements IListAccessibilityProvider<Settin
}
}
export class TOCTree extends ObjectTree<SettingsTreeGroupElement> {
export class TOCTree extends WorkbenchObjectTree<SettingsTreeGroupElement> {
constructor(
container: HTMLElement,
viewState: ISettingsEditorViewState,
@IContextKeyService contextKeyService: IContextKeyService,
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService keybindingService: IKeybindingService,
@IAccessibilityService accessibilityService: IAccessibilityService,
@IInstantiationService instantiationService: IInstantiationService,
) {
// test open mode
const filter = instantiationService.createInstance(SettingsTreeFilter, viewState);
const options: IObjectTreeOptions<SettingsTreeGroupElement> = {
const options: IWorkbenchObjectTreeOptions<SettingsTreeGroupElement, void> = {
filter,
multipleSelectionSupport: false,
identityProvider: {
......@@ -207,13 +216,23 @@ export class TOCTree extends ObjectTree<SettingsTreeGroupElement> {
},
styleController: id => new DefaultStyleController(DOM.createStyleSheet(container), id),
accessibilityProvider: instantiationService.createInstance(SettingsAccessibilityProvider),
collapseByDefault: true
collapseByDefault: true,
horizontalScrolling: false
};
super('SettingsTOC', container,
super(
'SettingsTOC',
container,
new TOCTreeDelegate(),
[new TOCRenderer()],
options);
options,
contextKeyService,
listService,
themeService,
configurationService,
keybindingService,
accessibilityService,
);
this.disposables.add(attachStyler(themeService, {
listBackground: editorBackground,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册