UNPKG

6.43 kBPlain TextView Raw
1// *****************************************************************************
2// Copyright (C) 2017 TypeFox and others.
3//
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License v. 2.0 which is available at
6// http://www.eclipse.org/legal/epl-2.0.
7//
8// This Source Code may also be made available under the following Secondary
9// Licenses when the conditions for such availability set forth in the Eclipse
10// Public License v. 2.0 are satisfied: GNU General Public License, version 2
11// with the GNU Classpath Exception which is available at
12// https://www.gnu.org/software/classpath/license.html.
13//
14// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15// *****************************************************************************
16
17import { interfaces, Container } from 'inversify';
18import { TreeWidget, TreeProps, defaultTreeProps } from './tree-widget';
19import { TreeModelImpl, TreeModel } from './tree-model';
20import { TreeImpl, Tree } from './tree';
21import { TreeSelectionService } from './tree-selection';
22import { TreeSelectionServiceImpl } from './tree-selection-impl';
23import { TreeExpansionService, TreeExpansionServiceImpl } from './tree-expansion';
24import { TreeNavigationService } from './tree-navigation';
25import { TreeDecoratorService, NoopTreeDecoratorService } from './tree-decorator';
26import { TreeSearch } from './tree-search';
27import { FuzzySearch } from './fuzzy-search';
28import { SearchBox, SearchBoxFactory } from './search-box';
29import { SearchBoxDebounce } from './search-box-debounce';
30import { TreeFocusService, TreeFocusServiceImpl } from './tree-focus-service';
31
32export function isTreeServices(candidate?: Partial<TreeProps> | Partial<TreeContainerProps>): candidate is TreeContainerProps {
33 if (candidate) {
34 const maybeServices = candidate as TreeContainerProps;
35 for (const key of Object.keys(maybeServices)) {
36 // This key is in both TreeProps and TreeContainerProps, so we have to handle it separately
37 if (key === 'search' && typeof maybeServices[key] === 'boolean') {
38 return false;
39 }
40 if (key in defaultImplementations) {
41 return true;
42 }
43 }
44 }
45 return false;
46}
47
48export function createTreeContainer(parent: interfaces.Container, props?: Partial<TreeContainerProps>): Container;
49/**
50 * @deprecated Please use TreeContainerProps instead of TreeProps
51 * @since 1.23.0
52 */
53export function createTreeContainer(parent: interfaces.Container, props?: Partial<TreeProps>): Container;
54export function createTreeContainer(parent: interfaces.Container, props?: Partial<TreeProps> | Partial<TreeContainerProps>): Container {
55 const child = new Container({ defaultScope: 'Singleton' });
56 child.parent = parent;
57 const overrideServices: Partial<TreeContainerProps> = isTreeServices(props) ? props : { props: props as Partial<TreeProps> | undefined };
58 for (const key of Object.keys(serviceIdentifiers) as (keyof TreeIdentifiers)[]) {
59 if (key === 'props') {
60 const { service, identifier } = getServiceAndIdentifier(key, overrideServices);
61 child.bind(identifier).toConstantValue({
62 ...defaultImplementations.props,
63 ...service
64 });
65 } else if (key === 'searchBoxFactory') {
66 const { service, identifier } = getServiceAndIdentifier(key, overrideServices);
67 child.bind(identifier).toFactory(context => service(context));
68 } else {
69 const { service, identifier } = getServiceAndIdentifier(key, overrideServices);
70 child.bind(service).toSelf().inSingletonScope();
71 if (identifier !== service) {
72 child.bind(identifier as interfaces.ServiceIdentifier<typeof service>).toService(service);
73 }
74 }
75 }
76 return child;
77}
78
79function getServiceAndIdentifier<Key extends keyof TreeIdentifiers>(
80 key: Key, overrides: Partial<TreeContainerProps>
81): { service: TreeContainerProps[Key], identifier: TreeIdentifiers[Key] } {
82 const override = overrides[key] as TreeContainerProps[Key] | undefined;
83 const service = override ?? defaultImplementations[key];
84 return {
85 service,
86 identifier: serviceIdentifiers[key]
87 };
88}
89
90export interface SearchBoxFactoryFactory {
91 (context: interfaces.Context): SearchBoxFactory;
92}
93
94const defaultSearchBoxFactoryFactory: SearchBoxFactoryFactory = () => options => {
95 const debounce = new SearchBoxDebounce(options);
96 return new SearchBox(options, debounce);
97};
98
99interface TreeConstants {
100 searchBoxFactory: SearchBoxFactory,
101 props: TreeProps,
102}
103
104interface TreeServices {
105 tree: Tree,
106 selectionService: TreeSelectionService,
107 expansionService: TreeExpansionService,
108 navigationService: TreeNavigationService,
109 model: TreeModel,
110 widget: TreeWidget,
111 search: TreeSearch,
112 fuzzy: FuzzySearch,
113 decoratorService: TreeDecoratorService,
114 focusService: TreeFocusService,
115}
116
117interface TreeTypes extends TreeServices, TreeConstants { }
118
119export type TreeIdentifiers = { [K in keyof TreeTypes]: interfaces.ServiceIdentifier<TreeTypes[K]>; };
120type TreeServiceProviders = { [K in keyof TreeServices]: interfaces.Newable<TreeServices[K]> };
121
122export interface TreeContainerProps extends TreeServiceProviders {
123 props: Partial<TreeProps>,
124 searchBoxFactory: SearchBoxFactoryFactory;
125}
126
127const defaultImplementations: TreeContainerProps & { props: TreeProps } = {
128 tree: TreeImpl,
129 selectionService: TreeSelectionServiceImpl,
130 expansionService: TreeExpansionServiceImpl,
131 navigationService: TreeNavigationService,
132 model: TreeModelImpl,
133 widget: TreeWidget,
134 search: TreeSearch,
135 fuzzy: FuzzySearch,
136 decoratorService: NoopTreeDecoratorService,
137 focusService: TreeFocusServiceImpl,
138 props: defaultTreeProps,
139 searchBoxFactory: defaultSearchBoxFactoryFactory,
140};
141
142const serviceIdentifiers: TreeIdentifiers = {
143 tree: Tree,
144 selectionService: TreeSelectionService,
145 expansionService: TreeExpansionService,
146 navigationService: TreeNavigationService,
147 model: TreeModel,
148 widget: TreeWidget,
149 props: TreeProps,
150 search: TreeSearch,
151 fuzzy: FuzzySearch,
152 searchBoxFactory: SearchBoxFactory,
153 decoratorService: TreeDecoratorService,
154 focusService: TreeFocusService
155};