UNPKG

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