extensionEditor.ts 17.7 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

J
Joao Moreno 已提交
8
import 'vs/css!./media/extensionEditor';
J
Joao Moreno 已提交
9
import { localize } from 'vs/nls';
J
Joao Moreno 已提交
10 11
import { TPromise } from 'vs/base/common/winjs.base';
import { marked } from 'vs/base/common/marked/marked';
J
Joao Moreno 已提交
12
import { always } from 'vs/base/common/async';
J
Joao Moreno 已提交
13
import * as arrays from 'vs/base/common/arrays';
J
Joao Moreno 已提交
14
import Event, { Emitter, once } from 'vs/base/common/event';
J
Joao Moreno 已提交
15
import Cache from 'vs/base/common/cache';
J
Joao Moreno 已提交
16
import { Action } from 'vs/base/common/actions';
17
import { onUnexpectedError } from 'vs/base/common/errors';
J
Joao Moreno 已提交
18
import { IDisposable, empty, dispose, toDisposable } from 'vs/base/common/lifecycle';
J
Joao Moreno 已提交
19
import { Builder } from 'vs/base/browser/builder';
20
import { domEvent } from 'vs/base/browser/event';
21
import { append, $, addClass, removeClass, finalHandler, join } from 'vs/base/browser/dom';
J
Joao Moreno 已提交
22
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
23
import { IViewlet } from 'vs/workbench/common/viewlet';
J
Joao Moreno 已提交
24
import { IViewletService } from 'vs/workbench/services/viewlet/common/viewletService';
J
Joao Moreno 已提交
25 26
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
27
import { IExtensionGalleryService, IExtensionManifest, IKeyBinding } from 'vs/platform/extensionManagement/common/extensionManagement';
J
Joao Moreno 已提交
28
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
29
import { ExtensionsInput } from './extensionsInput';
J
Joao Moreno 已提交
30
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension } from './extensions';
31
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
J
Joao Moreno 已提交
32
import { ITemplateData } from './extensionsList';
33
import { RatingsWidget, InstallWidget } from './extensionsWidgets';
J
Joao Moreno 已提交
34
import { EditorOptions } from 'vs/workbench/common/editor';
J
Joao Moreno 已提交
35 36
import { shell } from 'electron';
import product from 'vs/platform/product';
J
Joao Moreno 已提交
37
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
38
import { CombinedInstallAction, UpdateAction, EnableAction } from './extensionsActions';
J
Joao Moreno 已提交
39
import WebView from 'vs/workbench/parts/html/browser/webview';
40
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
J
Joao Moreno 已提交
41 42
import { Keybinding } from 'vs/base/common/keyCodes';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
J
Joao Moreno 已提交
43 44 45 46 47 48 49 50 51 52 53

function renderBody(body: string): string {
	return `<!DOCTYPE html>
		<html>
			<head>
				<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
				<link rel="stylesheet" type="text/css" href="${ require.toUrl('./media/markdown.css') }" >
			</head>
			<body>${ body }</body>
		</html>`;
}
J
Joao Moreno 已提交
54

J
Joao Moreno 已提交
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
class NavBar {

	private _onChange = new Emitter<string>();
	get onChange(): Event<string> { return this._onChange.event; }

	private actions: Action[];
	private actionbar: ActionBar;

	constructor(container: HTMLElement) {
		const element = append(container, $('.navbar'));
		this.actions = [];
		this.actionbar = new ActionBar(element, { animated: false });
	}

	push(id: string, label: string): void {
		const run = () => {
			this._onChange.fire(id);
			this.actions.forEach(a => a.enabled = a.id !== action.id);
			return TPromise.as(null);
		};

		const action = new Action(id, label, null, true, run);

		this.actions.push(action);
		this.actionbar.push(action);

		if (this.actions.length === 1) {
			run();
		}
	}

	clear(): void {
		this.actions = dispose(this.actions);
		this.actionbar.clear();
	}

	dispose(): void {
		this.actionbar = dispose(this.actionbar);
	}
}

const NavbarSection = {
	Readme: 'readme',
98
	Contributions: 'contributions'
J
Joao Moreno 已提交
99 100
};

J
Joao Moreno 已提交
101 102 103 104
export class ExtensionEditor extends BaseEditor {

	static ID: string = 'workbench.editor.extension';

105
	private icon: HTMLImageElement;
J
Joao Moreno 已提交
106
	private name: HTMLAnchorElement;
J
Joao Moreno 已提交
107
	private license: HTMLAnchorElement;
J
Joao Moreno 已提交
108
	private publisher: HTMLAnchorElement;
J
Joao Moreno 已提交
109
	private installCount: HTMLElement;
J
Joao Moreno 已提交
110
	private rating: HTMLAnchorElement;
J
Joao Moreno 已提交
111
	private description: HTMLElement;
J
Joao Moreno 已提交
112 113 114
	private extensionActionBar: ActionBar;
	private navbar: NavBar;
	private content: HTMLElement;
J
Joao Moreno 已提交
115 116 117 118

	private _highlight: ITemplateData;
	private highlightDisposable: IDisposable;

J
Joao Moreno 已提交
119 120 121
	private extensionReadme: Cache<string>;
	private extensionManifest: Cache<IExtensionManifest>;

J
Joao Moreno 已提交
122 123
	private contentDisposables: IDisposable[] = [];
	private transientDisposables: IDisposable[] = [];
J
Joao Moreno 已提交
124
	private disposables: IDisposable[];
J
Joao Moreno 已提交
125 126 127

	constructor(
		@ITelemetryService telemetryService: ITelemetryService,
128 129
		@IExtensionGalleryService private galleryService: IExtensionGalleryService,
		@IConfigurationService private configurationService: IConfigurationService,
J
Joao Moreno 已提交
130
		@IInstantiationService private instantiationService: IInstantiationService,
131
		@IViewletService private viewletService: IViewletService,
J
Joao Moreno 已提交
132
		@IExtensionsWorkbenchService private extensionsWorkbenchService: IExtensionsWorkbenchService,
133
		@IThemeService private themeService: IThemeService,
J
Joao Moreno 已提交
134 135
		@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
		@IKeybindingService private keybindingService: IKeybindingService
J
Joao Moreno 已提交
136 137 138 139
	) {
		super(ExtensionEditor.ID, telemetryService);
		this._highlight = null;
		this.highlightDisposable = empty;
J
Joao Moreno 已提交
140
		this.disposables = [];
J
Joao Moreno 已提交
141 142
		this.extensionReadme = null;
		this.extensionManifest = null;
143

144
		this.disposables.push(viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables));
J
Joao Moreno 已提交
145 146 147 148
	}

	createEditor(parent: Builder): void {
		const container = parent.getHTMLElement();
J
Joao Moreno 已提交
149 150 151

		const root = append(container, $('.extension-editor'));
		const header = append(root, $('.header'));
J
Joao Moreno 已提交
152

153
		this.icon = append(header, $<HTMLImageElement>('img.icon'));
J
Joao Moreno 已提交
154

J
Joao Moreno 已提交
155
		const details = append(header, $('.details'));
J
Joao Moreno 已提交
156 157
		const title = append(details, $('.title'));
		this.name = append(title, $<HTMLAnchorElement>('a.name'));
J
Joao Moreno 已提交
158
		this.name.href = '#';
J
Joao Moreno 已提交
159 160

		const subtitle = append(details, $('.subtitle'));
J
Joao Moreno 已提交
161 162
		this.publisher = append(subtitle, $<HTMLAnchorElement>('a.publisher'));
		this.publisher.href = '#';
J
Joao Moreno 已提交
163

164
		this.installCount = append(subtitle, $('span.install'));
J
Joao Moreno 已提交
165

J
Joao Moreno 已提交
166 167
		this.rating = append(subtitle, $<HTMLAnchorElement>('a.rating'));
		this.rating.href = '#';
J
Joao Moreno 已提交
168

J
Joao Moreno 已提交
169 170 171
		this.license = append(subtitle, $<HTMLAnchorElement>('a.license'));
		this.license.href = '#';
		this.license.textContent = localize('license', 'License');
172
		this.license.style.display = 'none';
J
Joao Moreno 已提交
173

J
Joao Moreno 已提交
174 175
		this.description = append(details, $('.description'));

J
Joao Moreno 已提交
176 177 178 179 180 181
		const extensionActions = append(details, $('.actions'));
		this.extensionActionBar = new ActionBar(extensionActions, { animated: false });
		this.disposables.push(this.extensionActionBar);

		const body = append(root, $('.body'));
		this.navbar = new NavBar(body);
J
Joao Moreno 已提交
182

J
Joao Moreno 已提交
183
		this.content = append(body, $('.content'));
J
Joao Moreno 已提交
184 185 186
	}

	setInput(input: ExtensionsInput, options: EditorOptions): TPromise<void> {
J
Joao Moreno 已提交
187 188
		this.transientDisposables = dispose(this.transientDisposables);

J
Joao Moreno 已提交
189
		const extension = input.extension;
190
		this.telemetryService.publicLog('extensionGallery:openExtension', extension.telemetryData);
J
Joao Moreno 已提交
191

J
Joao Moreno 已提交
192 193 194
		this.extensionReadme = new Cache(() => extension.getReadme());
		this.extensionManifest = new Cache(() => extension.getManifest());

195 196 197 198
		const onError = once(domEvent(this.icon, 'error'));
		onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
		this.icon.src = extension.iconUrl;

J
Joao Moreno 已提交
199 200 201
		this.name.textContent = extension.displayName;
		this.publisher.textContent = extension.publisherDisplayName;
		this.description.textContent = extension.description;
J
Joao Moreno 已提交
202

J
Joao Moreno 已提交
203 204 205
		if (product.extensionsGallery) {
			const extensionUrl = `${ product.extensionsGallery.itemUrl }?itemName=${ extension.publisher }.${ extension.name }`;

J
Joao Moreno 已提交
206 207 208
			this.name.onclick = finalHandler(() => shell.openExternal(extensionUrl));
			this.rating.onclick = finalHandler(() => shell.openExternal(`${ extensionUrl }#review-details`));
			this.publisher.onclick = finalHandler(() => {
209
				this.viewletService.openViewlet(VIEWLET_ID, true)
J
Joao Moreno 已提交
210 211 212
					.then(viewlet => viewlet as IExtensionsViewlet)
					.done(viewlet => viewlet.search(`publisher:"${ extension.publisherDisplayName }"`, true));
			});
213 214 215 216 217 218 219 220

			if (extension.licenseUrl) {
				this.license.onclick = finalHandler(() => shell.openExternal(extension.licenseUrl));
				this.license.style.display = 'initial';
			} else {
				this.license.onclick = null;
				this.license.style.display = 'none';
			}
J
Joao Moreno 已提交
221 222
		}

J
Joao Moreno 已提交
223
		const install = this.instantiationService.createInstance(InstallWidget, this.installCount, { extension });
J
Joao Moreno 已提交
224 225
		this.transientDisposables.push(install);

J
Joao Moreno 已提交
226
		const ratings = this.instantiationService.createInstance(RatingsWidget, this.rating, { extension });
J
Joao Moreno 已提交
227
		this.transientDisposables.push(ratings);
J
Joao Moreno 已提交
228

J
Joao Moreno 已提交
229 230 231 232 233 234 235 236
		const installAction = this.instantiationService.createInstance(CombinedInstallAction);
		const updateAction = this.instantiationService.createInstance(UpdateAction);
		const enableAction = this.instantiationService.createInstance(EnableAction);

		installAction.extension = extension;
		updateAction.extension = extension;
		enableAction.extension = extension;

J
Joao Moreno 已提交
237 238
		this.extensionActionBar.clear();
		this.extensionActionBar.push([enableAction, updateAction, installAction], { icon: true, label: true });
239
		this.transientDisposables.push(enableAction, updateAction, installAction);
J
Joao Moreno 已提交
240

J
Joao Moreno 已提交
241 242
		this.navbar.clear();
		this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables);
243 244
		this.navbar.push(NavbarSection.Readme, localize('details', "Details"));
		this.navbar.push(NavbarSection.Contributions, localize('contributions', "Contributions"));
J
Joao Moreno 已提交
245 246 247 248 249 250 251 252 253

		this.content.innerHTML = '';

		return super.setInput(input, options);
	}

	private onNavbarChange(extension: IExtension, id: string): void {
		switch (id) {
			case NavbarSection.Readme: return this.openReadme(extension);
254
			case NavbarSection.Contributions: return this.openContributions(extension);
J
Joao Moreno 已提交
255
		}
J
Joao Moreno 已提交
256
	}
J
Joao Moreno 已提交
257

J
Joao Moreno 已提交
258
	private openReadme(extension: IExtension) {
J
Joao Moreno 已提交
259
		return this.loadContents(() => this.extensionReadme.get()
J
Joao Moreno 已提交
260
			.then(marked.parse)
J
Joao Moreno 已提交
261
			.then(renderBody)
J
Joao Moreno 已提交
262 263 264 265 266 267 268
			.then<void>(body => {
				const webview = new WebView(
					this.content,
					document.querySelector('.monaco-editor-background')
				);

				webview.style(this.themeService.getColorTheme());
J
Joao Moreno 已提交
269
				webview.contents = [body];
J
Joao Moreno 已提交
270 271 272 273 274

				const linkListener = webview.onDidClickLink(link => shell.openExternal(link.toString()));
				const themeListener = this.themeService.onDidColorThemeChange(themeId => webview.style(themeId));
				this.contentDisposables.push(webview, linkListener, themeListener);
			})
J
Joao Moreno 已提交
275 276 277
			.then(null, () => {
				const p = append(this.content, $('p'));
				p.textContent = localize('noReadme', "No README available.");
J
Joao Moreno 已提交
278
			}));
J
Joao Moreno 已提交
279
	}
J
Joao Moreno 已提交
280

281
	private openContributions(extension: IExtension) {
J
Joao Moreno 已提交
282
		return this.loadContents(() => this.extensionManifest.get()
283
			.then(manifest => {
J
Joao Moreno 已提交
284
				this.content.innerHTML = '';
285 286
				const content = append(this.content, $('div', { class: 'subcontent' }));

J
Joao Moreno 已提交
287
				ExtensionEditor.renderSettings(content, manifest);
J
Joao Moreno 已提交
288
				this.renderCommands(content, manifest);
J
Joao Moreno 已提交
289
				ExtensionEditor.renderLanguages(content, manifest);
J
Joao Moreno 已提交
290
				ExtensionEditor.renderThemes(content, manifest);
J
Joao Moreno 已提交
291
				ExtensionEditor.renderJSONValidation(content, manifest);
J
Joao Moreno 已提交
292
				ExtensionEditor.renderDebuggers(content, manifest);
293
			}));
J
Joao Moreno 已提交
294 295
	}

J
Joao Moreno 已提交
296 297 298
	private static renderSettings(container: HTMLElement, manifest: IExtensionManifest): void {
		const configuration = manifest.contributes.configuration;
		const properties = configuration && configuration.properties;
J
Joao Moreno 已提交
299
		const contrib = properties ? Object.keys(properties) : [];
J
Joao Moreno 已提交
300

J
Joao Moreno 已提交
301
		if (!contrib.length) {
J
Joao Moreno 已提交
302 303 304 305
			return;
		}

		append(container, $('details', { open: true },
J
Joao Moreno 已提交
306
			$('summary', null, localize('settings', "Settings ({0})", contrib.length)),
J
Joao Moreno 已提交
307
			$('table', null,
J
Joao Moreno 已提交
308
				$('tr', null, $('th', null, localize('setting name', "Name")), $('th', null, localize('description', "Description"))),
J
Joao Moreno 已提交
309
				...contrib.map(key => $('tr', null, $('td', null, $('code', null, key)), $('td', null, properties[key].description)))
J
Joao Moreno 已提交
310 311 312 313 314
			)
		));
	}

	private static renderDebuggers(container: HTMLElement, manifest: IExtensionManifest): void {
J
Joao Moreno 已提交
315
		const contrib = manifest.contributes.debuggers || [];
J
Joao Moreno 已提交
316

J
Joao Moreno 已提交
317
		if (!contrib.length) {
J
Joao Moreno 已提交
318 319 320 321
			return;
		}

		append(container, $('details', { open: true },
J
Joao Moreno 已提交
322
			$('summary', null, localize('debuggers', "Debuggers ({0})", contrib.length)),
J
Joao Moreno 已提交
323
			$('table', null,
J
Joao Moreno 已提交
324
				$('tr', null, $('th', null, localize('debugger name', "Name")), $('th', null, localize('runtime', "Runtime"))),
J
Joao Moreno 已提交
325
				...contrib.map(d => $('tr', null, $('td', null, d.label || d.type), $('td', null, d.runtime)))
J
Joao Moreno 已提交
326 327 328 329
			)
		));
	}

J
Joao Moreno 已提交
330
	private static renderThemes(container: HTMLElement, manifest: IExtensionManifest): void {
J
Joao Moreno 已提交
331
		const contrib = manifest.contributes.themes || [];
J
Joao Moreno 已提交
332

J
Joao Moreno 已提交
333
		if (!contrib.length) {
J
Joao Moreno 已提交
334 335 336 337
			return;
		}

		append(container, $('details', { open: true },
J
Joao Moreno 已提交
338
			$('summary', null, localize('themes', "Themes ({0})", contrib.length)),
J
Joao Moreno 已提交
339
			$('ul', null,
J
Joao Moreno 已提交
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
				...contrib.map(theme => $('li', null, theme.label))
			)
		));
	}

	private static renderJSONValidation(container: HTMLElement, manifest: IExtensionManifest): void {
		const contrib = manifest.contributes.jsonValidation || [];

		if (!contrib.length) {
			return;
		}

		append(container, $('details', { open: true },
			$('summary', null, localize('JSON Validation', "JSON Validation ({0})", contrib.length)),
			$('ul', null,
				...contrib.map(v => $('li', null, v.fileMatch))
J
Joao Moreno 已提交
356 357 358 359
			)
		));
	}

J
Joao Moreno 已提交
360
	private renderCommands(container: HTMLElement, manifest: IExtensionManifest): void {
J
Joao Moreno 已提交
361 362
		const rawCommands = manifest.contributes.commands || [];
		const commands = rawCommands.map(c => ({
363 364
			id: c.command,
			title: c.title,
J
Joao Moreno 已提交
365
			keybindings: [],
366 367 368
			menus: []
		}));

J
Joao Moreno 已提交
369
		const byId = arrays.index(commands, c => c.id);
370 371

		const menus = manifest.contributes.menus || {};
J
Joao Moreno 已提交
372

373 374
		Object.keys(menus).forEach(context => {
			menus[context].forEach(menu => {
J
Joao Moreno 已提交
375
				let command = byId[menu.command];
376 377

				if (!command) {
J
Joao Moreno 已提交
378
					command = { id: menu.command, title: '', keybindings: [], menus: [context] };
J
Joao Moreno 已提交
379
					byId[command.id] = command;
380 381 382 383 384 385 386
					commands.push(command);
				} else {
					command.menus.push(context);
				}
			});
		});

J
Joao Moreno 已提交
387 388
		const rawKeybindings = manifest.contributes.keybindings || [];

389 390
		rawKeybindings.forEach(rawKeybinding => {
			const keyLabel = this.keybindingToLabel(rawKeybinding);
J
Joao Moreno 已提交
391
			let command = byId[rawKeybinding.command];
J
Joao Moreno 已提交
392 393

			if (!command) {
394
				command = { id: rawKeybinding.command, title: '', keybindings: [keyLabel], menus: [] };
J
Joao Moreno 已提交
395
				byId[command.id] = command;
J
Joao Moreno 已提交
396 397
				commands.push(command);
			} else {
398
				command.keybindings.push(keyLabel);
J
Joao Moreno 已提交
399 400 401
			}
		});

402 403 404 405 406 407 408 409 410 411
		if (!commands.length) {
			return;
		}

		append(container, $('details', { open: true },
			$('summary', null, localize('commands', "Commands ({0})", commands.length)),
			$('table', null,
				$('tr', null,
					$('th', null, localize('command name', "Name")),
					$('th', null, localize('description', "Description")),
J
Joao Moreno 已提交
412
					$('th', null, localize('keyboard shortcuts', "Keyboard Shortcuts")),
413 414 415
					$('th', null, localize('menuContexts', "Menu Contexts"))
				),
				...commands.map(c => $('tr', null,
416
					$('td', null, $('code', null, c.id)),
417
					$('td', null, c.title),
418
					$('td', null, ...join(c.keybindings.map(keybinding => $('code', null, keybinding)), ' ')),
419 420 421 422 423 424
					$('td', null, ...c.menus.map(context => $('code', null, context)))
				))
			)
		));
	}

J
Joao Moreno 已提交
425 426 427 428
	private static renderLanguages(container: HTMLElement, manifest: IExtensionManifest): void {
		const rawLanguages = manifest.contributes.languages || [];
		const languages = rawLanguages.map(l => ({
			id: l.id,
J
Joao Moreno 已提交
429 430 431
			name: (l.aliases || [])[0] || l.id,
			extensions: l.extensions,
			hasGrammar: false
J
Joao Moreno 已提交
432 433
		}));

J
Joao Moreno 已提交
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
		const byId = arrays.index(languages, l => l.id);

		const grammars = manifest.contributes.grammars || [];

		grammars.forEach(grammar => {
			let language = byId[grammar.language];

			if (!language) {
				language = { id: grammar.language, name: grammar.language, extensions: [], hasGrammar: true };
				byId[language.id] = language;
				languages.push(language);
			} else {
				language.hasGrammar = true;
			}
		});

J
Joao Moreno 已提交
450 451 452 453 454 455 456 457 458
		if (!languages.length) {
			return;
		}

		append(container, $('details', { open: true },
			$('summary', null, localize('languages', "Languages ({0})", languages.length)),
			$('table', null,
				$('tr', null,
					$('th', null, localize('command name', "Name")),
J
Joao Moreno 已提交
459 460
					$('th', null, localize('file extensions', "File Extensions")),
					$('th', null, localize('grammar', "Grammar"))
J
Joao Moreno 已提交
461 462 463
				),
				...languages.map(l => $('tr', null,
					$('td', null, l.name),
J
Joao Moreno 已提交
464 465
					$('td', null, ...join(l.extensions.map(ext => $('code', null, ext)), ' ')),
					$('td', null, document.createTextNode(l.hasGrammar ? '✔︎' : ''))
J
Joao Moreno 已提交
466 467 468 469 470
				))
			)
		));
	}

471 472 473 474 475 476 477 478 479 480 481 482 483
	private keybindingToLabel(rawKeyBinding: IKeyBinding): string {
		let key: string;

		switch(process.platform) {
			case 'win32': key = rawKeyBinding.win; break;
			case 'linux': key = rawKeyBinding.linux; break;
			case 'darwin': key = rawKeyBinding.mac; break;
		}

		const keyBinding = new Keybinding(Keybinding.fromUserSettingsLabel(key || rawKeyBinding.key));
		return this.keybindingService.getLabelFor(keyBinding);
	}

J
Joao Moreno 已提交
484 485 486
	private loadContents(loadingTask: ()=>TPromise<any>): void {
		this.contentDisposables = dispose(this.contentDisposables);

J
Joao Moreno 已提交
487
		this.content.innerHTML = '';
J
Joao Moreno 已提交
488
		addClass(this.content, 'loading');
J
Joao Moreno 已提交
489

J
Joao Moreno 已提交
490 491
		let promise = loadingTask();
		promise = always(promise, () => removeClass(this.content, 'loading'));
J
Joao Moreno 已提交
492

J
Joao Moreno 已提交
493
		this.contentDisposables.push(toDisposable(() => promise.cancel()));
J
Joao Moreno 已提交
494 495 496 497 498 499
	}

	layout(): void {
		return;
	}

500
	private onViewletOpen(viewlet: IViewlet): void {
501 502 503 504 505 506 507
		if (!viewlet || viewlet.getId() === VIEWLET_ID) {
			return;
		}

		this.editorService.closeEditor(this.position, this.input).done(null, onUnexpectedError);
	}

J
Joao Moreno 已提交
508 509
	dispose(): void {
		this._highlight = null;
J
Joao Moreno 已提交
510 511
		this.transientDisposables = dispose(this.transientDisposables);
		this.disposables = dispose(this.disposables);
J
Joao Moreno 已提交
512 513 514
		super.dispose();
	}
}