mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-26 09:45:54 +01:00
Settings editor - implement scroll on right based on left
This commit is contained in:
@@ -11,7 +11,6 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { getErrorMessage, isPromiseCanceledError } from 'vs/base/common/errors';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITree, ITreeConfiguration } from 'vs/base/parts/tree/browser/tree';
|
||||
import { DefaultTreestyler } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
@@ -31,10 +30,10 @@ import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
|
||||
import { EditorOptions, IEditor } from 'vs/workbench/common/editor';
|
||||
import { SearchWidget, SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
|
||||
import { tocData } from 'vs/workbench/parts/preferences/browser/settingsLayout';
|
||||
import { ISettingsEditorViewState, SearchResultIdx, SearchResultModel, SettingsAccessibilityProvider, SettingsDataSource, SettingsRenderer, SettingsTreeController, SettingsTreeFilter, TreeElement, isTOCLeaf } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
import { TOCDataSource, TOCRenderer } from 'vs/workbench/parts/preferences/browser/tocTree';
|
||||
import { ISettingsEditorViewState, SearchResultIdx, SearchResultModel, SettingsAccessibilityProvider, SettingsDataSource, SettingsRenderer, SettingsTreeController, SettingsTreeElement, SettingsTreeFilter, SettingsTreeModel } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
import { getTOCElement, TOCDataSource, TOCRenderer } from 'vs/workbench/parts/preferences/browser/tocTree';
|
||||
import { CONTEXT_SETTINGS_EDITOR, CONTEXT_SETTINGS_SEARCH_FOCUS, IPreferencesSearchService, ISearchProvider } from 'vs/workbench/parts/preferences/common/preferences';
|
||||
import { IPreferencesService, ISearchResult, ISetting, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IPreferencesService, ISearchResult, ISettingsEditorModel } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { SettingsEditor2Input } from 'vs/workbench/services/preferences/common/preferencesEditorInput';
|
||||
import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels';
|
||||
|
||||
@@ -56,10 +55,10 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
private settingsTreeContainer: HTMLElement;
|
||||
private settingsTree: WorkbenchTree;
|
||||
private treeDataSource: SettingsDataSource;
|
||||
private settingsTreeModel: SettingsTreeModel;
|
||||
|
||||
private tocTreeContainer: HTMLElement;
|
||||
private tocTree: WorkbenchTree;
|
||||
private resolvedTocData: IResolvedTOCEntry;
|
||||
|
||||
private delayedFilterLogging: Delayer<void>;
|
||||
private localSearchDelayer: Delayer<void>;
|
||||
@@ -69,7 +68,7 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
private settingUpdateDelayer: Delayer<void>;
|
||||
private pendingSettingUpdate: { key: string, value: any };
|
||||
|
||||
private selectedElement: TreeElement;
|
||||
private selectedElement: SettingsTreeElement;
|
||||
|
||||
private viewState: ISettingsEditorViewState;
|
||||
private searchResultModel: SearchResultModel;
|
||||
@@ -240,7 +239,8 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
});
|
||||
|
||||
this._register(this.tocTree.onDidChangeSelection(e => {
|
||||
this.settingsTree.reveal(e.selection[0], .1);
|
||||
const element = this.settingsTreeModel.getElementById(e.selection[0] && e.selection[0].id);
|
||||
this.settingsTree.reveal(element, 0);
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -445,12 +445,12 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
|
||||
this.defaultSettingsEditorModel = model;
|
||||
// if (!this.settingsTree.getInput()) {
|
||||
this.resolvedTocData = resolveSettingsTree(tocData, this.defaultSettingsEditorModel);
|
||||
this.tocTree.setInput(this.resolvedTocData);
|
||||
this.settingsTree.setInput(this.resolvedTocData);
|
||||
this.tocTree.setInput(getTOCElement(tocData));
|
||||
|
||||
this.expandAll(this.settingsTree);
|
||||
this.expandAll(this.tocTree);
|
||||
this.settingsTreeModel = this.instantiationService.createInstance(SettingsTreeModel, this.viewState, tocData, this.defaultSettingsEditorModel.settingsGroups.slice(1));
|
||||
this.settingsTree.setInput(this.settingsTreeModel.root);
|
||||
this.expandAll(this.settingsTree);
|
||||
this.expandAll(this.tocTree);
|
||||
// }
|
||||
});
|
||||
}
|
||||
@@ -505,7 +505,7 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
}
|
||||
|
||||
this.searchResultModel = null;
|
||||
this.settingsTree.setInput(this.resolvedTocData);
|
||||
this.settingsTree.setInput(this.settingsTreeModel.root);
|
||||
this.expandAll(this.settingsTree);
|
||||
this.expandAll(this.tocTree);
|
||||
|
||||
@@ -634,75 +634,3 @@ export class SettingsEditor2 extends BaseEditor {
|
||||
this.tocTree.layout(listHeight, 200);
|
||||
}
|
||||
}
|
||||
|
||||
export interface ITOCEntry<T> {
|
||||
id: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ITOCGroupEntry<T> extends ITOCEntry<T> {
|
||||
children?: ITOCEntry<T>[];
|
||||
}
|
||||
|
||||
export interface ITOCLeafEntry<T> extends ITOCEntry<T> {
|
||||
settings?: T[];
|
||||
}
|
||||
|
||||
export type IRawTOCEntry = ITOCGroupEntry<string> | ITOCLeafEntry<string>;
|
||||
export type IResolvedTOCEntry = ITOCGroupEntry<ISetting> | ITOCLeafEntry<ISetting>;
|
||||
|
||||
function resolveSettingsTree(tocData: IRawTOCEntry, defaultSettings: DefaultSettingsEditorModel): IResolvedTOCEntry {
|
||||
return _resolveSettingsTree(tocData, getAllSettings(defaultSettings));
|
||||
}
|
||||
|
||||
function _resolveSettingsTree(tocData: IRawTOCEntry, allSettings: Set<ISetting>): IResolvedTOCEntry {
|
||||
if (isTOCLeaf(tocData)) {
|
||||
return <IResolvedTOCEntry>{
|
||||
id: tocData.id,
|
||||
label: tocData.label,
|
||||
settings: arrays.flatten(tocData.settings.map(pattern => getMatchingSettings(allSettings, pattern)))
|
||||
};
|
||||
} else {
|
||||
return <IResolvedTOCEntry>{
|
||||
id: tocData.id,
|
||||
label: tocData.label,
|
||||
children: tocData.children.map(child => _resolveSettingsTree(child, allSettings))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function getMatchingSettings(allSettings: Set<ISetting>, pattern: string): ISetting[] {
|
||||
const result: ISetting[] = [];
|
||||
|
||||
allSettings.forEach(s => {
|
||||
if (settingMatches(s, pattern)) {
|
||||
result.push(s);
|
||||
allSettings.delete(s);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return result.sort((a, b) => a.key.localeCompare(b.key));
|
||||
}
|
||||
|
||||
function settingMatches(s: ISetting, pattern: string): boolean {
|
||||
pattern = escapeRegExpCharacters(pattern)
|
||||
.replace(/\\\*/g, '.*');
|
||||
|
||||
const regexp = new RegExp(`^${pattern}`, 'i');
|
||||
return regexp.test(s.key);
|
||||
}
|
||||
|
||||
function getAllSettings(defaultSettings: DefaultSettingsEditorModel) {
|
||||
const result: Set<ISetting> = new Set();
|
||||
|
||||
for (let group of defaultSettings.settingsGroups.slice(1)) {
|
||||
for (let section of group.sections) {
|
||||
for (let s of section.settings) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,179 +1,179 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRawTOCEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/tocTree';
|
||||
|
||||
export const tocData: IRawTOCEntry = {
|
||||
id: 'root',
|
||||
label: 'root',
|
||||
children: [
|
||||
export const tocData: ITOCEntry = {
|
||||
id: 'root',
|
||||
label: 'root',
|
||||
children: [
|
||||
{
|
||||
id: 'editor',
|
||||
label: 'Text Editor',
|
||||
children: [
|
||||
{
|
||||
id: 'editor.cursor',
|
||||
label: 'Cursor',
|
||||
settings: ['editor.cursor*']
|
||||
},
|
||||
{
|
||||
id: 'editor.find',
|
||||
label: 'Find',
|
||||
settings: ['editor.find.*']
|
||||
},
|
||||
{
|
||||
id: 'editor.font',
|
||||
label: 'Font',
|
||||
settings: ['editor.font*']
|
||||
},
|
||||
{
|
||||
id: 'editor.format',
|
||||
label: 'Format',
|
||||
settings: ['editor.format*']
|
||||
},
|
||||
{
|
||||
id: 'editor.diff',
|
||||
label: 'Diff Editor',
|
||||
settings: ['diffEditor.*']
|
||||
},
|
||||
{
|
||||
id: 'editor.minimap',
|
||||
label: 'Minimap',
|
||||
settings: ['editor.minimap.*']
|
||||
},
|
||||
{
|
||||
id: 'editor.suggestions',
|
||||
label: 'Suggestions',
|
||||
settings: ['editor.*suggestion*']
|
||||
},
|
||||
{
|
||||
id: 'editor.files',
|
||||
label: 'Files',
|
||||
settings: ['files.*']
|
||||
},
|
||||
{
|
||||
id: 'editor.editor',
|
||||
label: 'Editor',
|
||||
settings: ['editor.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'workbench',
|
||||
label: 'Workbench',
|
||||
children: [
|
||||
id: 'editor',
|
||||
label: 'Text Editor',
|
||||
children: [
|
||||
{
|
||||
id: 'workbench.appearance',
|
||||
label: 'Appearance',
|
||||
settings: ['workbench.activityBar.*', 'workbench.*color*', 'workbench.fontAliasing', 'workbench.iconTheme', 'workbench.sidebar.location', 'workbench.*.visible', 'workbench.tips.enabled', 'workbench.tree.*', 'workbench.view.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench.editor',
|
||||
label: 'Editor Management',
|
||||
settings: ['workbench.editor.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench.zenmode',
|
||||
label: 'Zen Mode',
|
||||
settings: ['zenmode.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench.workbench',
|
||||
label: 'Workbench',
|
||||
settings: ['workbench.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'window',
|
||||
label: 'Window',
|
||||
children: [
|
||||
{
|
||||
id: 'window.newWindow',
|
||||
label: 'New Window',
|
||||
settings: ['window.*newwindow*']
|
||||
},
|
||||
{
|
||||
id: 'window.window',
|
||||
label: 'Window',
|
||||
settings: ['window.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'features',
|
||||
label: 'Features',
|
||||
children: [
|
||||
{
|
||||
id: 'features.explorer',
|
||||
label: 'File Explorer',
|
||||
settings: ['explorer.*', 'outline.*']
|
||||
},
|
||||
{
|
||||
id: 'features.search',
|
||||
label: 'Search',
|
||||
settings: ['search.*']
|
||||
}
|
||||
,
|
||||
{
|
||||
id: 'features.debug',
|
||||
label: 'Debug',
|
||||
settings: ['debug.*', 'launch']
|
||||
},
|
||||
{
|
||||
id: 'features.scm',
|
||||
label: 'Source Control Management',
|
||||
settings: ['scm.*']
|
||||
},
|
||||
{
|
||||
id: 'features.extensions',
|
||||
label: 'Extension Viewlet',
|
||||
settings: ['extensions.*']
|
||||
},
|
||||
{
|
||||
id: 'features.terminal',
|
||||
label: 'Terminal',
|
||||
settings: ['terminal.*']
|
||||
},
|
||||
{
|
||||
id: 'features.problems',
|
||||
label: 'Problems',
|
||||
settings: ['problems.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'application',
|
||||
label: 'Application',
|
||||
children: [
|
||||
{
|
||||
id: 'application.http',
|
||||
label: 'Proxy',
|
||||
settings: ['http.*']
|
||||
},
|
||||
{
|
||||
id: 'application.keyboard',
|
||||
label: 'Keyboard',
|
||||
settings: ['keyboard.*']
|
||||
},
|
||||
{
|
||||
id: 'application.update',
|
||||
label: 'Update',
|
||||
settings: ['update.*']
|
||||
},
|
||||
{
|
||||
id: 'application.telemetry',
|
||||
label: 'Telemetry',
|
||||
settings: ['telemetry.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'extensions',
|
||||
label: 'Extensions',
|
||||
settings: ['*']
|
||||
}
|
||||
]
|
||||
id: 'editor/cursor',
|
||||
label: 'Cursor',
|
||||
settings: ['editor.cursor*']
|
||||
},
|
||||
{
|
||||
id: 'editor/find',
|
||||
label: 'Find',
|
||||
settings: ['editor.find.*']
|
||||
},
|
||||
{
|
||||
id: 'editor/font',
|
||||
label: 'Font',
|
||||
settings: ['editor.font*']
|
||||
},
|
||||
{
|
||||
id: 'editor/format',
|
||||
label: 'Format',
|
||||
settings: ['editor.format*']
|
||||
},
|
||||
{
|
||||
id: 'editor/diff',
|
||||
label: 'Diff Editor',
|
||||
settings: ['diffEditor.*']
|
||||
},
|
||||
{
|
||||
id: 'editor/minimap',
|
||||
label: 'Minimap',
|
||||
settings: ['editor.minimap.*']
|
||||
},
|
||||
{
|
||||
id: 'editor/suggestions',
|
||||
label: 'Suggestions',
|
||||
settings: ['editor.*suggestion*']
|
||||
},
|
||||
{
|
||||
id: 'editor/files',
|
||||
label: 'Files',
|
||||
settings: ['files.*']
|
||||
},
|
||||
{
|
||||
id: 'editor/editor',
|
||||
label: 'Editor',
|
||||
settings: ['editor.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'workbench',
|
||||
label: 'Workbench',
|
||||
children: [
|
||||
{
|
||||
id: 'workbench/appearance',
|
||||
label: 'Appearance',
|
||||
settings: ['workbench.activityBar.*', 'workbench.*color*', 'workbench.fontAliasing', 'workbench.iconTheme', 'workbench.sidebar.location', 'workbench.*.visible', 'workbench.tips.enabled', 'workbench.tree.*', 'workbench.view.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench/editor',
|
||||
label: 'Editor Management',
|
||||
settings: ['workbench.editor.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench/zenmode',
|
||||
label: 'Zen Mode',
|
||||
settings: ['zenmode.*']
|
||||
},
|
||||
{
|
||||
id: 'workbench/workbench',
|
||||
label: 'Workbench',
|
||||
settings: ['workbench.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'window',
|
||||
label: 'Window',
|
||||
children: [
|
||||
{
|
||||
id: 'window/newWindow',
|
||||
label: 'New Window',
|
||||
settings: ['window.*newwindow*']
|
||||
},
|
||||
{
|
||||
id: 'window/window',
|
||||
label: 'Window',
|
||||
settings: ['window.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'features',
|
||||
label: 'Features',
|
||||
children: [
|
||||
{
|
||||
id: 'features/explorer',
|
||||
label: 'File Explorer',
|
||||
settings: ['explorer.*', 'outline.*']
|
||||
},
|
||||
{
|
||||
id: 'features/search',
|
||||
label: 'Search',
|
||||
settings: ['search.*']
|
||||
}
|
||||
,
|
||||
{
|
||||
id: 'features/debug',
|
||||
label: 'Debug',
|
||||
settings: ['debug.*', 'launch']
|
||||
},
|
||||
{
|
||||
id: 'features/scm',
|
||||
label: 'Source Control Management',
|
||||
settings: ['scm.*']
|
||||
},
|
||||
{
|
||||
id: 'features/extensions',
|
||||
label: 'Extension Viewlet',
|
||||
settings: ['extensions.*']
|
||||
},
|
||||
{
|
||||
id: 'features/terminal',
|
||||
label: 'Terminal',
|
||||
settings: ['terminal.*']
|
||||
},
|
||||
{
|
||||
id: 'features/problems',
|
||||
label: 'Problems',
|
||||
settings: ['problems.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'application',
|
||||
label: 'Application',
|
||||
children: [
|
||||
{
|
||||
id: 'application/http',
|
||||
label: 'Proxy',
|
||||
settings: ['http.*']
|
||||
},
|
||||
{
|
||||
id: 'application/keyboard',
|
||||
label: 'Keyboard',
|
||||
settings: ['keyboard.*']
|
||||
},
|
||||
{
|
||||
id: 'application/update',
|
||||
label: 'Update',
|
||||
settings: ['update.*']
|
||||
},
|
||||
{
|
||||
id: 'application/telemetry',
|
||||
label: 'Telemetry',
|
||||
settings: ['telemetry.*']
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'extensions',
|
||||
label: 'Extensions',
|
||||
settings: ['*']
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as arrays from 'vs/base/common/arrays';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
@@ -25,8 +26,9 @@ import { editorActiveLinkForeground, registerColor } from 'vs/platform/theme/com
|
||||
import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler } from 'vs/platform/theme/common/styler';
|
||||
import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets';
|
||||
import { IResolvedTOCEntry, ITOCGroupEntry, ITOCLeafEntry, ITOCEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { ISearchResult, ISetting } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { ISearchResult, ISetting, ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { ITOCEntry } from 'vs/workbench/parts/preferences/browser/tocTree';
|
||||
import { escapeRegExpCharacters } from 'vs/base/common/strings';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
@@ -43,20 +45,20 @@ registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
|
||||
}
|
||||
});
|
||||
|
||||
export interface ITreeItem {
|
||||
export abstract class SettingsTreeElement {
|
||||
id: string;
|
||||
parent: SettingsTreeElement;
|
||||
}
|
||||
|
||||
export enum TreeItemType {
|
||||
setting,
|
||||
groupTitle
|
||||
export class SettingsTreeGroupElement extends SettingsTreeElement {
|
||||
children: (SettingsTreeGroupElement | SettingsTreeSettingElement)[];
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface ISettingElement extends ITreeItem {
|
||||
type: TreeItemType.setting;
|
||||
export class SettingsTreeSettingElement extends SettingsTreeElement {
|
||||
setting: ISetting;
|
||||
|
||||
parent: IGroupElement | SearchResultModel;
|
||||
isExpanded: boolean;
|
||||
displayCategory: string;
|
||||
displayLabel: string;
|
||||
value: any;
|
||||
@@ -67,44 +69,49 @@ export interface ISettingElement extends ITreeItem {
|
||||
enum?: string[];
|
||||
}
|
||||
|
||||
export interface IGroupElement extends ITreeItem {
|
||||
type: TreeItemType.groupTitle;
|
||||
parent: IGroupElement | IResolvedTOCEntry;
|
||||
group: IResolvedTOCEntry;
|
||||
index: number;
|
||||
}
|
||||
export class SettingsTreeModel {
|
||||
private _root: SettingsTreeElement;
|
||||
private _treeElementsById = new Map<string, SettingsTreeElement>();
|
||||
|
||||
export type TreeElement = ISettingElement | IGroupElement;
|
||||
export type TreeElementOrRoot = TreeElement | IResolvedTOCEntry | SearchResultModel;
|
||||
|
||||
function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): { isConfigured: boolean, inspected: any, targetSelector: string } {
|
||||
const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined;
|
||||
const inspected = configurationService.inspect(key, inspectOverrides);
|
||||
const targetSelector = target === ConfigurationTarget.USER ? 'user' :
|
||||
target === ConfigurationTarget.WORKSPACE ? 'workspace' :
|
||||
'workspaceFolder';
|
||||
const isConfigured = typeof inspected[targetSelector] !== 'undefined';
|
||||
|
||||
return { isConfigured, inspected, targetSelector };
|
||||
}
|
||||
|
||||
export class SettingsDataSource implements IDataSource {
|
||||
constructor(
|
||||
private viewState: ISettingsEditorViewState,
|
||||
tocRoot: ITOCEntry,
|
||||
allSettings: ISettingsGroup[],
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
) { }
|
||||
|
||||
getGroupElement(group: IResolvedTOCEntry, parent: IGroupElement | IResolvedTOCEntry, index: number): IGroupElement {
|
||||
return <IGroupElement>{
|
||||
type: TreeItemType.groupTitle,
|
||||
group,
|
||||
parent,
|
||||
id: sanitizeElementId(group.id),
|
||||
index
|
||||
};
|
||||
) {
|
||||
const resolvedTOC = resolveSettingsTree(tocRoot, allSettings);
|
||||
this._root = this.createSettingsTreeGroupElement(resolvedTOC);
|
||||
}
|
||||
|
||||
getSettingElement(setting: ISetting, parent: IGroupElement | SearchResultModel, category: string): ISettingElement {
|
||||
get root(): SettingsTreeElement {
|
||||
return this._root;
|
||||
}
|
||||
|
||||
getElementById(id: string): SettingsTreeElement {
|
||||
return this._treeElementsById.get(id);
|
||||
}
|
||||
|
||||
private createSettingsTreeGroupElement(tocEntry: ITOCEntry, parent?: SettingsTreeGroupElement): SettingsTreeGroupElement {
|
||||
const element = new SettingsTreeGroupElement();
|
||||
element.id = tocEntry.id;
|
||||
element.label = tocEntry.label;
|
||||
element.parent = parent;
|
||||
|
||||
if (tocEntry.children) {
|
||||
element.children = tocEntry.children.map(child => this.createSettingsTreeGroupElement(child, element));
|
||||
} else if (tocEntry.settings) {
|
||||
element.children = tocEntry.settings.map(s => this.createSettingsTreeSettingElement(<ISetting>s, element));
|
||||
}
|
||||
|
||||
this._treeElementsById.set(element.id, element);
|
||||
return element;
|
||||
}
|
||||
|
||||
private createSettingsTreeSettingElement(setting: ISetting, parent: SettingsTreeGroupElement): SettingsTreeSettingElement {
|
||||
const element = new SettingsTreeSettingElement();
|
||||
element.id = setting.key;
|
||||
element.parent = parent;
|
||||
|
||||
const { isConfigured, inspected, targetSelector } = inspectSetting(setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
|
||||
const displayValue = isConfigured ? inspected[targetSelector] : inspected.default;
|
||||
@@ -117,96 +124,143 @@ export class SettingsDataSource implements IDataSource {
|
||||
overriddenScopeList.push(localize('user', "User"));
|
||||
}
|
||||
|
||||
const displayKeyFormat = settingKeyToDisplayFormat(setting.key, category);
|
||||
return <ISettingElement>{
|
||||
type: TreeItemType.setting,
|
||||
parent,
|
||||
id: sanitizeElementId(setting.key),
|
||||
setting,
|
||||
const displayKeyFormat = settingKeyToDisplayFormat(setting.key, parent.id);
|
||||
element.setting = setting;
|
||||
element.displayLabel = displayKeyFormat.label;
|
||||
element.displayCategory = displayKeyFormat.category;
|
||||
element.isExpanded = false;
|
||||
|
||||
displayLabel: displayKeyFormat.label,
|
||||
displayCategory: displayKeyFormat.category,
|
||||
isExpanded: false,
|
||||
element.value = displayValue;
|
||||
element.isConfigured = isConfigured;
|
||||
element.overriddenScopeList = overriddenScopeList;
|
||||
element.description = setting.description.join('\n');
|
||||
element.enum = setting.enum;
|
||||
element.valueType = setting.type;
|
||||
|
||||
value: displayValue,
|
||||
isConfigured,
|
||||
overriddenScopeList,
|
||||
description: setting.description.join('\n'),
|
||||
enum: setting.enum,
|
||||
valueType: setting.type
|
||||
this._treeElementsById.set(element.id, element);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
|
||||
function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): { isConfigured: boolean, inspected: any, targetSelector: string } {
|
||||
const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined;
|
||||
const inspected = configurationService.inspect(key, inspectOverrides);
|
||||
const targetSelector = target === ConfigurationTarget.USER ? 'user' :
|
||||
target === ConfigurationTarget.WORKSPACE ? 'workspace' :
|
||||
'workspaceFolder';
|
||||
const isConfigured = typeof inspected[targetSelector] !== 'undefined';
|
||||
|
||||
return { isConfigured, inspected, targetSelector };
|
||||
}
|
||||
|
||||
function resolveSettingsTree(tocData: ITOCEntry, settingsGroups: ISettingsGroup[]): ITOCEntry {
|
||||
return _resolveSettingsTree(tocData, getFlatSettings(settingsGroups));
|
||||
}
|
||||
|
||||
function _resolveSettingsTree(tocData: ITOCEntry, allSettings: Set<ISetting>): ITOCEntry {
|
||||
if (tocData.settings) {
|
||||
return <ITOCEntry>{
|
||||
id: tocData.id,
|
||||
label: tocData.label,
|
||||
settings: arrays.flatten(tocData.settings.map(pattern => getMatchingSettings(allSettings, <string>pattern)))
|
||||
};
|
||||
} else if (tocData.children) {
|
||||
return <ITOCEntry>{
|
||||
id: tocData.id,
|
||||
label: tocData.label,
|
||||
children: tocData.children.map(child => _resolveSettingsTree(child, allSettings))
|
||||
};
|
||||
}
|
||||
|
||||
getId(tree: ITree, element: TreeElementOrRoot): string {
|
||||
return null;
|
||||
}
|
||||
|
||||
function getMatchingSettings(allSettings: Set<ISetting>, pattern: string): ISetting[] {
|
||||
const result: ISetting[] = [];
|
||||
|
||||
allSettings.forEach(s => {
|
||||
if (settingMatches(s, pattern)) {
|
||||
result.push(s);
|
||||
allSettings.delete(s);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return result.sort((a, b) => a.key.localeCompare(b.key));
|
||||
}
|
||||
|
||||
function settingMatches(s: ISetting, pattern: string): boolean {
|
||||
pattern = escapeRegExpCharacters(pattern)
|
||||
.replace(/\\\*/g, '.*');
|
||||
|
||||
const regexp = new RegExp(`^${pattern}`, 'i');
|
||||
return regexp.test(s.key);
|
||||
}
|
||||
|
||||
function getFlatSettings(settingsGroups: ISettingsGroup[]) {
|
||||
const result: Set<ISetting> = new Set();
|
||||
|
||||
for (let group of settingsGroups) {
|
||||
for (let section of group.sections) {
|
||||
for (let s of section.settings) {
|
||||
result.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
export class SettingsDataSource implements IDataSource {
|
||||
|
||||
getId(tree: ITree, element: SettingsTreeElement): string {
|
||||
return element.id;
|
||||
}
|
||||
|
||||
hasChildren(tree: ITree, element: TreeElementOrRoot): boolean {
|
||||
if (isTOCRoot(element)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
hasChildren(tree: ITree, element: SettingsTreeElement): boolean {
|
||||
if (element instanceof SearchResultModel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.groupTitle) {
|
||||
if (element instanceof SettingsTreeGroupElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private _getChildren(element: TreeElementOrRoot): TreeElement[] {
|
||||
if (isTOCRoot(element)) {
|
||||
return this.getRootChildren(element);
|
||||
} else if (element instanceof SearchResultModel) {
|
||||
private getSearchResultChildren(searchResult: SearchResultModel): SettingsTreeSettingElement[] {
|
||||
return searchResult.getFlatSettings()
|
||||
.map(s => this.getSettingElement(s, searchResult, 'searchResult'));
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: SettingsTreeElement): TPromise<any, any> {
|
||||
return TPromise.as(this._getChildren(element));
|
||||
}
|
||||
|
||||
private _getChildren(element: SettingsTreeElement): SettingsTreeElement[] {
|
||||
if (element instanceof SearchResultModel) {
|
||||
return this.getSearchResultChildren(element);
|
||||
} else if (element.type === TreeItemType.groupTitle) {
|
||||
} else if (element instanceof SettingsTreeGroupElement) {
|
||||
return this.getGroupChildren(element);
|
||||
} else {
|
||||
// No children...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private getSearchResultChildren(searchResult: SearchResultModel): ISettingElement[] {
|
||||
return searchResult.getFlatSettings()
|
||||
.map(s => this.getSettingElement(s, searchResult, 'searchResult'));
|
||||
private getGroupChildren(groupElement: SettingsTreeGroupElement): SettingsTreeElement[] {
|
||||
return groupElement.children;
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: TreeElementOrRoot): TPromise<any, any> {
|
||||
return TPromise.as(this._getChildren(element));
|
||||
getParent(tree: ITree, element: SettingsTreeElement): TPromise<any, any> {
|
||||
return TPromise.wrap(element.parent);
|
||||
}
|
||||
|
||||
private getRootChildren(root: ITOCGroupEntry<ISetting>): TreeElement[] {
|
||||
return root.children
|
||||
.map((g, i) => this.getGroupElement(g, root, i));
|
||||
}
|
||||
|
||||
private getGroupChildren(groupElement: IGroupElement): TreeElement[] {
|
||||
return isTOCLeaf(groupElement.group) ?
|
||||
groupElement.group.settings.map(s => this.getSettingElement(s, groupElement, groupElement.id)) :
|
||||
groupElement.group.children.map((child, i) => this.getGroupElement(child, groupElement, i));
|
||||
}
|
||||
|
||||
getParent(tree: ITree, element: TreeElementOrRoot): TPromise<any, any> {
|
||||
return TPromise.wrap(
|
||||
isTOCRoot(element) ? null :
|
||||
element instanceof SearchResultModel ? null :
|
||||
element.parent);
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeElementId(id: string): string {
|
||||
return id.replace(/\./g, '_');
|
||||
}
|
||||
|
||||
function isTOCRoot(element: TreeElementOrRoot): element is IResolvedTOCEntry {
|
||||
return element.id === 'root';
|
||||
}
|
||||
|
||||
export function settingKeyToDisplayFormat(key: string, groupId: string): { category: string, label: string } {
|
||||
groupId = groupId.replace(/\//g, '.');
|
||||
|
||||
let label = key
|
||||
.replace(/\.([a-z])/g, (match, p1) => `.${p1.toUpperCase()}`)
|
||||
.replace(/([a-z])([A-Z])/g, '$1 $2') // fooBar => foo Bar
|
||||
@@ -267,7 +321,7 @@ interface IDisposableTemplate {
|
||||
interface ISettingItemTemplate extends IDisposableTemplate {
|
||||
parent: HTMLElement;
|
||||
|
||||
context?: ISettingElement;
|
||||
context?: SettingsTreeSettingElement;
|
||||
containerElement: HTMLElement;
|
||||
categoryElement: HTMLElement;
|
||||
labelElement: HTMLElement;
|
||||
@@ -278,7 +332,7 @@ interface ISettingItemTemplate extends IDisposableTemplate {
|
||||
}
|
||||
|
||||
interface IGroupTitleTemplate extends IDisposableTemplate {
|
||||
context?: IGroupElement;
|
||||
context?: SettingsTreeGroupElement;
|
||||
parent: HTMLElement;
|
||||
labelElement: HTMLElement;
|
||||
}
|
||||
@@ -311,12 +365,12 @@ export class SettingsRenderer implements IRenderer {
|
||||
this.measureContainer = DOM.append(_measureContainer, $('.setting-measure-container.monaco-tree-row'));
|
||||
}
|
||||
|
||||
getHeight(tree: ITree, element: TreeElement): number {
|
||||
if (element.type === TreeItemType.groupTitle) {
|
||||
getHeight(tree: ITree, element: SettingsTreeElement): number {
|
||||
if (element instanceof SettingsTreeGroupElement) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.setting) {
|
||||
if (element instanceof SettingsTreeSettingElement) {
|
||||
const isSelected = this.elementIsSelected(tree, element);
|
||||
if (isSelected) {
|
||||
return this.measureSettingElementHeight(tree, element);
|
||||
@@ -328,7 +382,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private measureSettingElementHeight(tree: ITree, element: ISettingElement): number {
|
||||
private measureSettingElementHeight(tree: ITree, element: SettingsTreeSettingElement): number {
|
||||
const measureHelper = DOM.append(this.measureContainer, $('.setting-measure-helper'));
|
||||
|
||||
const template = this.renderSettingTemplate(tree, measureHelper);
|
||||
@@ -339,12 +393,12 @@ export class SettingsRenderer implements IRenderer {
|
||||
return Math.max(height, SettingsRenderer.SETTING_ROW_HEIGHT);
|
||||
}
|
||||
|
||||
getTemplateId(tree: ITree, element: TreeElement): string {
|
||||
if (element.type === TreeItemType.groupTitle) {
|
||||
getTemplateId(tree: ITree, element: SettingsTreeElement): string {
|
||||
if (element instanceof SettingsTreeGroupElement) {
|
||||
return SETTINGS_GROUP_ELEMENT_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.setting) {
|
||||
if (element instanceof SettingsTreeSettingElement) {
|
||||
return SETTINGS_ELEMENT_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
@@ -417,24 +471,24 @@ export class SettingsRenderer implements IRenderer {
|
||||
return template;
|
||||
}
|
||||
|
||||
renderElement(tree: ITree, element: TreeElement, templateId: string, template: any): void {
|
||||
renderElement(tree: ITree, element: SettingsTreeElement, templateId: string, template: any): void {
|
||||
if (templateId === SETTINGS_ELEMENT_TEMPLATE_ID) {
|
||||
return this.renderSettingElement(tree, <ISettingElement>element, template);
|
||||
return this.renderSettingElement(tree, <SettingsTreeSettingElement>element, template);
|
||||
}
|
||||
|
||||
if (templateId === SETTINGS_GROUP_ELEMENT_TEMPLATE_ID) {
|
||||
(<IGroupTitleTemplate>template).labelElement.textContent = (<IGroupElement>element).group.label;
|
||||
(<IGroupTitleTemplate>template).labelElement.textContent = (<SettingsTreeGroupElement>element).label;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private elementIsSelected(tree: ITree, element: TreeElement): boolean {
|
||||
private elementIsSelected(tree: ITree, element: SettingsTreeElement): boolean {
|
||||
const selection = tree.getSelection();
|
||||
const selectedElement: TreeElement = selection && selection[0];
|
||||
const selectedElement: SettingsTreeElement = selection && selection[0];
|
||||
return selectedElement && selectedElement.id === element.id;
|
||||
}
|
||||
|
||||
private renderSettingElement(tree: ITree, element: ISettingElement, template: ISettingItemTemplate): void {
|
||||
private renderSettingElement(tree: ITree, element: SettingsTreeSettingElement, template: ISettingItemTemplate): void {
|
||||
const isSelected = !!this.elementIsSelected(tree, element);
|
||||
const setting = element.setting;
|
||||
|
||||
@@ -482,7 +536,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private renderValue(element: ISettingElement, isSelected: boolean, template: ISettingItemTemplate): void {
|
||||
private renderValue(element: SettingsTreeSettingElement, isSelected: boolean, template: ISettingItemTemplate): void {
|
||||
const onChange = value => this._onDidChangeSetting.fire({ key: element.setting.key, value });
|
||||
template.valueElement.innerHTML = '';
|
||||
const valueControlElement = DOM.append(template.valueElement, $('.setting-item-control'));
|
||||
@@ -504,7 +558,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private renderBool(dataElement: ISettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: boolean) => void): void {
|
||||
private renderBool(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: boolean) => void): void {
|
||||
const checkboxElement = <HTMLInputElement>DOM.append(element, $('input.setting-value-checkbox.setting-value-input'));
|
||||
checkboxElement.type = 'checkbox';
|
||||
checkboxElement.checked = dataElement.value;
|
||||
@@ -513,7 +567,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
template.toDispose.push(DOM.addDisposableListener(checkboxElement, 'change', e => onChange(checkboxElement.checked)));
|
||||
}
|
||||
|
||||
private renderEnum(dataElement: ISettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: string) => void): void {
|
||||
private renderEnum(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: string) => void): void {
|
||||
const idx = dataElement.enum.indexOf(dataElement.value);
|
||||
const displayOptions = dataElement.enum.map(escapeInvisibleChars);
|
||||
const selectBox = new SelectBox(displayOptions, idx, this.contextViewService);
|
||||
@@ -527,7 +581,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
selectBox.onDidSelect(e => onChange(dataElement.enum[e.index])));
|
||||
}
|
||||
|
||||
private renderText(dataElement: ISettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: string) => void): void {
|
||||
private renderText(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement, onChange: (value: string) => void): void {
|
||||
const inputBox = new InputBox(element, this.contextViewService);
|
||||
template.toDispose.push(attachInputBoxStyler(inputBox, this.themeService));
|
||||
template.toDispose.push(inputBox);
|
||||
@@ -538,7 +592,7 @@ export class SettingsRenderer implements IRenderer {
|
||||
inputBox.onDidChange(e => onChange(e)));
|
||||
}
|
||||
|
||||
private renderEditInSettingsJson(dataElement: ISettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement): void {
|
||||
private renderEditInSettingsJson(dataElement: SettingsTreeSettingElement, isSelected: boolean, template: ISettingItemTemplate, element: HTMLElement): void {
|
||||
const openSettingsButton = new Button(element, { title: true, buttonBackground: null, buttonHoverBackground: null });
|
||||
openSettingsButton.onDidClick(() => this._onDidOpenSettings.fire());
|
||||
openSettingsButton.label = localize('editInSettingsJson', "Edit in settings.json");
|
||||
@@ -570,28 +624,30 @@ export class SettingsTreeFilter implements IFilter {
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
) { }
|
||||
|
||||
isVisible(tree: ITree, element: TreeElement): boolean {
|
||||
if (this.viewState.showConfiguredOnly && element.type === TreeItemType.setting) {
|
||||
isVisible(tree: ITree, element: SettingsTreeElement): boolean {
|
||||
if (this.viewState.showConfiguredOnly && element instanceof SettingsTreeSettingElement) {
|
||||
return element.isConfigured;
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.groupTitle && this.viewState.showConfiguredOnly) {
|
||||
return this.groupHasConfiguredSetting(element.group);
|
||||
if (element instanceof SettingsTreeGroupElement && this.viewState.showConfiguredOnly) {
|
||||
return this.groupHasConfiguredSetting(element);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private groupHasConfiguredSetting(element: IResolvedTOCEntry): boolean {
|
||||
if (isTOCLeaf(element)) {
|
||||
for (let setting of element.settings) {
|
||||
const { isConfigured } = inspectSetting(setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
private groupHasConfiguredSetting(element: SettingsTreeGroupElement): boolean {
|
||||
for (let child of element.children) {
|
||||
if (child instanceof SettingsTreeSettingElement) {
|
||||
const { isConfigured } = inspectSetting(child.setting.key, this.viewState.settingsTarget, this.configurationService);
|
||||
if (isConfigured) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (child instanceof SettingsTreeGroupElement) {
|
||||
return this.groupHasConfiguredSetting(child);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return element.children.some(c => this.groupHasConfiguredSetting(c));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -607,17 +663,17 @@ export class SettingsTreeController extends WorkbenchTreeController {
|
||||
}
|
||||
|
||||
export class SettingsAccessibilityProvider implements IAccessibilityProvider {
|
||||
getAriaLabel(tree: ITree, element: TreeElement): string {
|
||||
getAriaLabel(tree: ITree, element: SettingsTreeElement): string {
|
||||
if (!element) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.setting) {
|
||||
if (element instanceof SettingsTreeSettingElement) {
|
||||
return localize('settingRowAriaLabel', "{0} {1}, Setting", element.displayCategory, element.displayLabel);
|
||||
}
|
||||
|
||||
if (element.type === TreeItemType.groupTitle) {
|
||||
return localize('groupRowAriaLabel', "{0}, group", element.group.label);
|
||||
if (element instanceof SettingsTreeGroupElement) {
|
||||
return localize('groupRowAriaLabel', "{0}, group", element.label);
|
||||
}
|
||||
|
||||
return '';
|
||||
@@ -681,7 +737,3 @@ export class SearchResultModel {
|
||||
return flatSettings;
|
||||
}
|
||||
}
|
||||
|
||||
export function isTOCLeaf<T>(entry: ITOCEntry<T>): entry is ITOCLeafEntry<T> {
|
||||
return !!(<ITOCLeafEntry<T>>entry).settings;
|
||||
}
|
||||
|
||||
@@ -6,32 +6,53 @@
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDataSource, IRenderer, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IResolvedTOCEntry, ITOCGroupEntry } from 'vs/workbench/parts/preferences/browser/settingsEditor2';
|
||||
import { ISetting } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { isTOCLeaf } from 'vs/workbench/parts/preferences/browser/settingsTree';
|
||||
|
||||
const $ = DOM.$;
|
||||
|
||||
// export interface ITOCRoot {
|
||||
// id: string;
|
||||
// children: ITOCEntry[];
|
||||
// }
|
||||
export interface ITOCEntry {
|
||||
id: string;
|
||||
label: string;
|
||||
children?: ITOCEntry[];
|
||||
settings?: (string | ISetting)[];
|
||||
}
|
||||
|
||||
export class TOCElement {
|
||||
id: string;
|
||||
label: string;
|
||||
|
||||
parent?: TOCElement;
|
||||
children?: TOCElement[];
|
||||
}
|
||||
|
||||
export function getTOCElement(tocRoot: ITOCEntry, parent?: TOCElement): TOCElement {
|
||||
const element = new TOCElement();
|
||||
element.id = tocRoot.id;
|
||||
element.label = tocRoot.label;
|
||||
|
||||
element.parent = parent;
|
||||
if (tocRoot.children) {
|
||||
element.children = tocRoot.children.map(child => getTOCElement(child, element));
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
export class TOCDataSource implements IDataSource {
|
||||
getId(tree: ITree, element: IResolvedTOCEntry): string {
|
||||
getId(tree: ITree, element: TOCElement): string {
|
||||
return element.id;
|
||||
}
|
||||
|
||||
hasChildren(tree: ITree, element: IResolvedTOCEntry): boolean {
|
||||
return !isTOCLeaf(element) && element.children.length && typeof element.children[0] !== 'string';
|
||||
hasChildren(tree: ITree, element: TOCElement): boolean {
|
||||
return !!(element.children && element.children.length);
|
||||
}
|
||||
|
||||
getChildren(tree: ITree, element: ITOCGroupEntry<ISetting>): TPromise<IResolvedTOCEntry[], any> {
|
||||
return TPromise.as(<IResolvedTOCEntry[]>element.children);
|
||||
getChildren(tree: ITree, element: TOCElement): TPromise<TOCElement[], any> {
|
||||
return TPromise.as(<TOCElement[]>element.children);
|
||||
}
|
||||
|
||||
getParent(tree: ITree, element: IResolvedTOCEntry): TPromise<any, any> {
|
||||
return TPromise.wrap(null); // ??
|
||||
getParent(tree: ITree, element: TOCElement): TPromise<any, any> {
|
||||
return TPromise.wrap(element.parent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,11 +63,11 @@ interface ITOCEntryTemplate {
|
||||
}
|
||||
|
||||
export class TOCRenderer implements IRenderer {
|
||||
getHeight(tree: ITree, element: IResolvedTOCEntry): number {
|
||||
getHeight(tree: ITree, element: TOCElement): number {
|
||||
return 22;
|
||||
}
|
||||
|
||||
getTemplateId(tree: ITree, element: IResolvedTOCEntry): string {
|
||||
getTemplateId(tree: ITree, element: TOCElement): string {
|
||||
return TOC_ENTRY_TEMPLATE_ID;
|
||||
}
|
||||
|
||||
@@ -56,7 +77,7 @@ export class TOCRenderer implements IRenderer {
|
||||
};
|
||||
}
|
||||
|
||||
renderElement(tree: ITree, element: IResolvedTOCEntry, templateId: string, template: ITOCEntryTemplate): void {
|
||||
renderElement(tree: ITree, element: TOCElement, templateId: string, template: ITOCEntryTemplate): void {
|
||||
template.element.textContent = element.label;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user