UNPKG

13.2 kBJavaScriptView Raw
1"use strict";
2// *****************************************************************************
3// Copyright (C) 2017 TypeFox and others.
4//
5// This program and the accompanying materials are made available under the
6// terms of the Eclipse Public License v. 2.0 which is available at
7// http://www.eclipse.org/legal/epl-2.0.
8//
9// This Source Code may also be made available under the following Secondary
10// Licenses when the conditions for such availability set forth in the Eclipse
11// Public License v. 2.0 are satisfied: GNU General Public License, version 2
12// with the GNU Classpath Exception which is available at
13// https://www.gnu.org/software/classpath/license.html.
14//
15// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16// *****************************************************************************
17Object.defineProperty(exports, "__esModule", { value: true });
18exports.LabelProvider = exports.DefaultUriLabelProviderContribution = exports.URIIconReference = exports.LabelProviderContribution = void 0;
19const tslib_1 = require("tslib");
20const inversify_1 = require("inversify");
21const fileIcons = require("file-icons-js");
22const uri_1 = require("../common/uri");
23const contribution_provider_1 = require("../common/contribution-provider");
24const common_1 = require("../common");
25const env_variables_protocol_1 = require("../common/env-variables/env-variables-protocol");
26const widgets_1 = require("./widgets");
27/**
28 * @internal don't export it, use `LabelProvider.folderIcon` instead.
29 */
30const DEFAULT_FOLDER_ICON = `${(0, widgets_1.codicon)('folder')} default-folder-icon`;
31/**
32 * @internal don't export it, use `LabelProvider.fileIcon` instead.
33 */
34const DEFAULT_FILE_ICON = `${(0, widgets_1.codicon)('file')} default-file-icon`;
35exports.LabelProviderContribution = Symbol('LabelProviderContribution');
36var URIIconReference;
37(function (URIIconReference) {
38 function is(element) {
39 return (0, common_1.isObject)(element) && element.kind === 'uriIconReference';
40 }
41 URIIconReference.is = is;
42 function create(id, uri) {
43 return { kind: 'uriIconReference', id, uri };
44 }
45 URIIconReference.create = create;
46})(URIIconReference = exports.URIIconReference || (exports.URIIconReference = {}));
47let DefaultUriLabelProviderContribution = class DefaultUriLabelProviderContribution {
48 constructor() {
49 this.formatters = [];
50 this.onDidChangeEmitter = new common_1.Emitter();
51 // copied and modified from https://github.com/microsoft/vscode/blob/1.44.2/src/vs/workbench/services/label/common/labelService.ts
52 /*---------------------------------------------------------------------------------------------
53 * Copyright (c) Microsoft Corporation. All rights reserved.
54 * Licensed under the MIT License. See License.txt in the project root for license information.
55 *--------------------------------------------------------------------------------------------*/
56 this.labelMatchingRegexp = /\${(scheme|authority|path|query)}/g;
57 }
58 init() {
59 this.envVariablesServer.getHomeDirUri().then(result => {
60 this.homePath = result;
61 this.fireOnDidChange();
62 });
63 }
64 canHandle(element) {
65 if (element instanceof uri_1.default || URIIconReference.is(element)) {
66 return 1;
67 }
68 return 0;
69 }
70 getIcon(element) {
71 if (URIIconReference.is(element) && element.id === 'folder') {
72 return this.defaultFolderIcon;
73 }
74 const uri = URIIconReference.is(element) ? element.uri : element;
75 if (uri) {
76 const iconClass = uri && this.getFileIcon(uri);
77 return iconClass || this.defaultFileIcon;
78 }
79 return '';
80 }
81 get defaultFolderIcon() {
82 return DEFAULT_FOLDER_ICON;
83 }
84 get defaultFileIcon() {
85 return DEFAULT_FILE_ICON;
86 }
87 getFileIcon(uri) {
88 const fileIcon = fileIcons.getClassWithColor(uri.displayName);
89 if (!fileIcon) {
90 return undefined;
91 }
92 return fileIcon + ' theia-file-icons-js';
93 }
94 getName(element) {
95 const uri = this.getUri(element);
96 return uri && uri.displayName;
97 }
98 getLongName(element) {
99 const uri = this.getUri(element);
100 if (uri) {
101 const formatting = this.findFormatting(uri);
102 if (formatting) {
103 return this.formatUri(uri, formatting);
104 }
105 }
106 return uri && uri.path.fsPath();
107 }
108 getDetails(element) {
109 const uri = this.getUri(element);
110 if (uri) {
111 return this.getLongName(uri.parent);
112 }
113 return this.getLongName(element);
114 }
115 getUri(element) {
116 return URIIconReference.is(element) ? element.uri : element;
117 }
118 registerFormatter(formatter) {
119 this.formatters.push(formatter);
120 this.fireOnDidChange();
121 return common_1.Disposable.create(() => {
122 this.formatters = this.formatters.filter(f => f !== formatter);
123 this.fireOnDidChange();
124 });
125 }
126 get onDidChange() {
127 return this.onDidChangeEmitter.event;
128 }
129 fireOnDidChange() {
130 this.onDidChangeEmitter.fire({
131 affects: (element) => this.canHandle(element) > 0
132 });
133 }
134 formatUri(resource, formatting) {
135 let label = formatting.label.replace(this.labelMatchingRegexp, (match, token) => {
136 switch (token) {
137 case 'scheme': return resource.scheme;
138 case 'authority': return resource.authority;
139 case 'path': return resource.path.toString();
140 case 'query': return resource.query;
141 default: return '';
142 }
143 });
144 // convert \c:\something => C:\something
145 if (formatting.normalizeDriveLetter && this.hasDriveLetter(label)) {
146 label = label.charAt(1).toUpperCase() + label.substring(2);
147 }
148 if (formatting.tildify) {
149 label = common_1.Path.tildify(label, this.homePath ? this.homePath : '');
150 }
151 if (formatting.authorityPrefix && resource.authority) {
152 label = formatting.authorityPrefix + label;
153 }
154 return label.replace(/\//g, formatting.separator);
155 }
156 hasDriveLetter(path) {
157 return !!(path && path[2] === ':');
158 }
159 findFormatting(resource) {
160 let bestResult;
161 this.formatters.forEach(formatter => {
162 if (formatter.scheme === resource.scheme) {
163 if (!bestResult && !formatter.authority) {
164 bestResult = formatter;
165 return;
166 }
167 if (!formatter.authority) {
168 return;
169 }
170 if ((formatter.authority.toLowerCase() === resource.authority.toLowerCase()) &&
171 (!bestResult || !bestResult.authority || formatter.authority.length > bestResult.authority.length ||
172 ((formatter.authority.length === bestResult.authority.length) && formatter.priority))) {
173 bestResult = formatter;
174 }
175 }
176 });
177 return bestResult ? bestResult.formatting : undefined;
178 }
179};
180(0, tslib_1.__decorate)([
181 (0, inversify_1.inject)(env_variables_protocol_1.EnvVariablesServer),
182 (0, tslib_1.__metadata)("design:type", Object)
183], DefaultUriLabelProviderContribution.prototype, "envVariablesServer", void 0);
184(0, tslib_1.__decorate)([
185 (0, inversify_1.postConstruct)(),
186 (0, tslib_1.__metadata)("design:type", Function),
187 (0, tslib_1.__metadata)("design:paramtypes", []),
188 (0, tslib_1.__metadata)("design:returntype", void 0)
189], DefaultUriLabelProviderContribution.prototype, "init", null);
190DefaultUriLabelProviderContribution = (0, tslib_1.__decorate)([
191 (0, inversify_1.injectable)()
192], DefaultUriLabelProviderContribution);
193exports.DefaultUriLabelProviderContribution = DefaultUriLabelProviderContribution;
194/**
195 * The {@link LabelProvider} determines how elements/nodes are displayed in the workbench. For any element, it can determine a short label, a long label
196 * and an icon. The {@link LabelProvider} is to be used in lists, trees and tables, but also view specific locations like headers.
197 * The common {@link LabelProvider} can be extended/adapted via {@link LabelProviderContribution}s. For every element, the {@links LabelProvider} will determine the
198 * {@link LabelProviderContribution} with the hightest priority and delegate to it. Theia registers default {@link LabelProviderContribution} for common types, e.g.
199 * the {@link DefaultUriLabelProviderContribution} for elements that have a URI.
200 * Using the {@link LabelProvider} across the workbench ensures a common look and feel for elements across multiple views. To adapt the way how specific
201 * elements/nodes are rendered, use a {@link LabelProviderContribution} rather than adapting or sub classing the {@link LabelProvider}. This way, your adaptation
202 * is applied to all views in Theia that use the {@link LabelProvider}
203 */
204let LabelProvider = class LabelProvider {
205 constructor() {
206 this.onDidChangeEmitter = new common_1.Emitter();
207 }
208 /**
209 * Start listening to contributions.
210 *
211 * Don't call this method directly!
212 * It's called by the frontend application during initialization.
213 */
214 initialize() {
215 const contributions = this.contributionProvider.getContributions();
216 for (const eventContribution of contributions) {
217 if (eventContribution.onDidChange) {
218 eventContribution.onDidChange(event => {
219 this.onDidChangeEmitter.fire({
220 // TODO check eventContribution.canHandle as well
221 affects: element => this.affects(element, event)
222 });
223 });
224 }
225 }
226 }
227 affects(element, event) {
228 if (event.affects(element)) {
229 return true;
230 }
231 for (const contribution of this.findContribution(element)) {
232 if (contribution.affects && contribution.affects(element, event)) {
233 return true;
234 }
235 }
236 return false;
237 }
238 get onDidChange() {
239 return this.onDidChangeEmitter.event;
240 }
241 /**
242 * Return a default file icon for the current icon theme.
243 */
244 get fileIcon() {
245 return this.getIcon(URIIconReference.create('file'));
246 }
247 /**
248 * Return a default folder icon for the current icon theme.
249 */
250 get folderIcon() {
251 return this.getIcon(URIIconReference.create('folder'));
252 }
253 /**
254 * Get the icon class from the list of available {@link LabelProviderContribution} for the given element.
255 * @return the icon class
256 */
257 getIcon(element) {
258 var _a;
259 return (_a = this.handleRequest(element, 'getIcon')) !== null && _a !== void 0 ? _a : '';
260 }
261 /**
262 * Get a short name from the list of available {@link LabelProviderContribution} for the given element.
263 * @return the short name
264 */
265 getName(element) {
266 var _a;
267 return (_a = this.handleRequest(element, 'getName')) !== null && _a !== void 0 ? _a : '<unknown>';
268 }
269 /**
270 * Get a long name from the list of available {@link LabelProviderContribution} for the given element.
271 * @return the long name
272 */
273 getLongName(element) {
274 var _a;
275 return (_a = this.handleRequest(element, 'getLongName')) !== null && _a !== void 0 ? _a : '';
276 }
277 /**
278 * Get details from the list of available {@link LabelProviderContribution} for the given element.
279 * @return the details
280 * Can be used to supplement {@link getName} in contexts that allow both a primary display field and extra detail.
281 */
282 getDetails(element) {
283 var _a;
284 return (_a = this.handleRequest(element, 'getDetails')) !== null && _a !== void 0 ? _a : '';
285 }
286 handleRequest(element, method) {
287 var _a;
288 for (const contribution of this.findContribution(element, method)) {
289 const value = (_a = contribution[method]) === null || _a === void 0 ? void 0 : _a.call(contribution, element);
290 if (value !== undefined) {
291 return value;
292 }
293 }
294 }
295 findContribution(element, method) {
296 const candidates = method
297 ? this.contributionProvider.getContributions().filter(candidate => candidate[method])
298 : this.contributionProvider.getContributions();
299 return common_1.Prioritizeable.prioritizeAllSync(candidates, contrib => contrib.canHandle(element)).map(entry => entry.value);
300 }
301};
302(0, tslib_1.__decorate)([
303 (0, inversify_1.inject)(contribution_provider_1.ContributionProvider),
304 (0, inversify_1.named)(exports.LabelProviderContribution),
305 (0, tslib_1.__metadata)("design:type", Object)
306], LabelProvider.prototype, "contributionProvider", void 0);
307LabelProvider = (0, tslib_1.__decorate)([
308 (0, inversify_1.injectable)()
309], LabelProvider);
310exports.LabelProvider = LabelProvider;
311//# sourceMappingURL=label-provider.js.map
\No newline at end of file