shell.ts 26.2 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

'use strict';

import 'vs/css!./media/shell';

10
import * as nls from 'vs/nls';
J
Joao Moreno 已提交
11
import * as platform from 'vs/base/common/platform';
J
Johannes Rieken 已提交
12
import { Dimension, Builder, $ } from 'vs/base/browser/builder';
E
Erich Gamma 已提交
13
import dom = require('vs/base/browser/dom');
14
import aria = require('vs/base/browser/ui/aria/aria');
J
Johannes Rieken 已提交
15
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
E
Erich Gamma 已提交
16
import errors = require('vs/base/common/errors');
J
Johannes Rieken 已提交
17
import { toErrorMessage } from 'vs/base/common/errorMessage';
18
import product from 'vs/platform/node/product';
19
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
20
import pkg from 'vs/platform/node/package';
J
Johannes Rieken 已提交
21
import { ContextViewService } from 'vs/platform/contextview/browser/contextViewService';
22
import { Workbench, IWorkbenchStartedInfo } from 'vs/workbench/electron-browser/workbench';
23
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
K
kieferrm 已提交
24
import { NullTelemetryService, configurationTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
25
import { IExperimentService, ExperimentService } from 'vs/platform/telemetry/common/experiments';
J
Johannes Rieken 已提交
26 27
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
J
Joao Moreno 已提交
28
import ErrorTelemetry from 'vs/platform/telemetry/browser/errorTelemetry';
29
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
30
import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/workbenchCommonProperties';
31
import { IWindowsService, IWindowService, IWindowConfiguration } from 'vs/platform/windows/common/windows';
J
Joao Moreno 已提交
32
import { WindowService } from 'vs/platform/windows/electron-browser/windowService';
J
Johannes Rieken 已提交
33
import { MessageService } from 'vs/workbench/services/message/electron-browser/messageService';
J
Joao Moreno 已提交
34
import { IRequestService } from 'vs/platform/request/node/request';
35
import { RequestService } from 'vs/platform/request/electron-browser/requestService';
J
Johannes Rieken 已提交
36 37 38 39 40 41 42
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { SearchService } from 'vs/workbench/services/search/node/searchService';
import { LifecycleService } from 'vs/workbench/services/lifecycle/electron-browser/lifecycleService';
import { MarkerService } from 'vs/platform/markers/common/markerService';
import { IModelService } from 'vs/editor/common/services/modelService';
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
import { CodeEditorServiceImpl } from 'vs/editor/browser/services/codeEditorServiceImpl';
43
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
J
Johannes Rieken 已提交
44 45 46 47
import { IntegrityServiceImpl } from 'vs/platform/integrity/node/integrityServiceImpl';
import { IIntegrityService } from 'vs/platform/integrity/common/integrity';
import { EditorWorkerServiceImpl } from 'vs/editor/common/services/editorWorkerServiceImpl';
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
48
import { ExtensionService } from 'vs/workbench/services/extensions/electron-browser/extensionService';
J
Johannes Rieken 已提交
49
import { IStorageService } from 'vs/platform/storage/common/storage';
J
Joao Moreno 已提交
50
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
J
Johannes Rieken 已提交
51 52 53
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
S
Sandeep Somavarapu 已提交
54
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
J
Johannes Rieken 已提交
55 56
import { IMarkerService } from 'vs/platform/markers/common/markers';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
B
Benjamin Pasero 已提交
57
import { IMessageService, IChoiceService, Severity } from 'vs/platform/message/common/message';
J
Johannes Rieken 已提交
58 59 60 61
import { ChoiceChannel } from 'vs/platform/message/common/messageIpc';
import { ISearchService } from 'vs/platform/search/common/search';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { CommandService } from 'vs/platform/commands/common/commandService';
62
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
63
import { IExtensionService } from 'vs/platform/extensions/common/extensions';
64
import { WorkbenchModeServiceImpl } from 'vs/workbench/services/mode/common/workbenchModeService';
J
Johannes Rieken 已提交
65 66
import { IModeService } from 'vs/editor/common/services/modeService';
import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
67
import { ICrashReporterService, NullCrashReporterService, CrashReporterService } from 'vs/workbench/services/crashReporter/electron-browser/crashReporterService';
J
Johannes Rieken 已提交
68 69 70
import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import { connect as connectNet } from 'vs/base/parts/ipc/node/ipc.net';
import { IExtensionManagementChannel, ExtensionManagementChannelClient } from 'vs/platform/extensionManagement/common/extensionManagementIpc';
71 72
import { IExtensionManagementService, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionEnablementService';
B
Benjamin Pasero 已提交
73
import { ITimerService } from 'vs/workbench/services/timer/common/timerService';
74
import { remote } from 'electron';
75
import { BareFontInfo } from 'vs/editor/common/config/fontInfo';
76 77
import { restoreFontInfo, readFontInfo, saveFontInfo } from 'vs/editor/browser/config/configuration';
import * as browser from 'vs/base/browser/browser';
78
import 'vs/platform/opener/browser/opener.contribution';
79 80
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { WorkbenchThemeService } from 'vs/workbench/services/themes/electron-browser/workbenchThemeService';
81 82
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { TextResourceConfigurationService } from 'vs/editor/common/services/resourceConfigurationImpl';
83
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
84
import { foreground, selectionBackground, focusBorder, scrollbarShadow, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, listHighlightForeground, inputPlaceholderForeground } from 'vs/platform/theme/common/colorRegistry';
85 86
import { TextMateService } from 'vs/workbench/services/textMate/electron-browser/TMSyntax';
import { ITextMateService } from 'vs/workbench/services/textMate/electron-browser/textMateService';
87
import { IBroadcastService, BroadcastService } from 'vs/platform/broadcast/electron-browser/broadcastService';
B
Benjamin Pasero 已提交
88 89
import { HashService } from 'vs/workbench/services/hash/node/hashService';
import { IHashService } from 'vs/workbench/services/hash/common/hashService';
J
Joao Moreno 已提交
90
import { ILogService } from 'vs/platform/log/common/log';
91

92 93 94 95 96 97
/**
 * Services that we require for the Shell
 */
export interface ICoreServices {
	contextService: IWorkspaceContextService;
	configurationService: IConfigurationService;
98
	environmentService: IEnvironmentService;
J
Joao Moreno 已提交
99
	logService: ILogService;
B
Benjamin Pasero 已提交
100
	timerService: ITimerService;
101
	storageService: IStorageService;
102 103
}

104 105
const currentWindow = remote.getCurrentWindow();

E
Erich Gamma 已提交
106
/**
B
Benjamin Pasero 已提交
107
 * The workbench shell contains the workbench with a rich header containing navigation and the activity bar.
E
Erich Gamma 已提交
108 109 110
 * With the Shell being the top level element in the page, it is also responsible for driving the layouting.
 */
export class WorkbenchShell {
B
Benjamin Pasero 已提交
111
	private storageService: IStorageService;
112
	private messageService: MessageService;
J
Johannes Rieken 已提交
113
	private environmentService: IEnvironmentService;
J
Joao Moreno 已提交
114
	private logService: ILogService;
B
Benjamin Pasero 已提交
115
	private contextViewService: ContextViewService;
116 117
	private configurationService: IConfigurationService;
	private contextService: IWorkspaceContextService;
118
	private telemetryService: ITelemetryService;
119
	private experimentService: IExperimentService;
120
	private extensionService: ExtensionService;
121
	private broadcastService: IBroadcastService;
B
Benjamin Pasero 已提交
122
	private timerService: ITimerService;
B
Benjamin Pasero 已提交
123
	private themeService: WorkbenchThemeService;
124
	private lifecycleService: LifecycleService;
125 126
	private mainProcessServices: ServiceCollection;

E
Erich Gamma 已提交
127
	private container: HTMLElement;
128
	private toUnbind: IDisposable[];
E
Erich Gamma 已提交
129 130 131 132 133
	private previousErrorValue: string;
	private previousErrorTime: number;
	private content: HTMLElement;
	private contentsContainer: Builder;

134
	private configuration: IWindowConfiguration;
E
Erich Gamma 已提交
135 136
	private workbench: Workbench;

B
Benjamin Pasero 已提交
137
	constructor(container: HTMLElement, coreServices: ICoreServices, mainProcessServices: ServiceCollection, configuration: IWindowConfiguration) {
E
Erich Gamma 已提交
138 139
		this.container = container;

140
		this.configuration = configuration;
141

B
Benjamin Pasero 已提交
142 143 144
		this.contextService = coreServices.contextService;
		this.configurationService = coreServices.configurationService;
		this.environmentService = coreServices.environmentService;
J
Joao Moreno 已提交
145
		this.logService = coreServices.logService;
B
Benjamin Pasero 已提交
146 147
		this.timerService = coreServices.timerService;
		this.storageService = coreServices.storageService;
E
Erich Gamma 已提交
148

149 150
		this.mainProcessServices = mainProcessServices;

E
Erich Gamma 已提交
151 152 153 154 155 156
		this.toUnbind = [];
		this.previousErrorTime = 0;
	}

	private createContents(parent: Builder): Builder {

157
		// ARIA
B
Benjamin Pasero 已提交
158
		aria.setARIAContainer(document.body);
159

E
Erich Gamma 已提交
160
		// Workbench Container
161
		const workbenchContainer = $(parent).div();
E
Erich Gamma 已提交
162 163

		// Instantiation service with services
164
		const [instantiationService, serviceCollection] = this.initServiceCollection(parent.getHTMLElement());
E
Erich Gamma 已提交
165 166

		// Workbench
167
		this.workbench = instantiationService.createInstance(Workbench, parent.getHTMLElement(), workbenchContainer.getHTMLElement(), this.configuration, serviceCollection, this.lifecycleService);
168
		try {
B
Benjamin Pasero 已提交
169
			this.workbench.startup().done(startupInfos => this.onWorkbenchStarted(startupInfos, instantiationService));
170 171
		} catch (error) {

172 173
			// Log it
			this.logService.error(toErrorMessage(error, true));
174 175 176 177

			// Rethrow
			throw error;
		}
E
Erich Gamma 已提交
178

179
		// Window
180
		this.workbench.getInstantiationService().createInstance(ElectronWindow, this.container);
E
Erich Gamma 已提交
181 182

		// Handle case where workbench is not starting up properly
183
		const timeoutHandle = setTimeout(() => {
184
			this.logService.warn('Workbench did not finish loading in 10 seconds, that might be a problem that should be reported.');
E
Erich Gamma 已提交
185 186
		}, 10000);

187
		this.lifecycleService.when(LifecyclePhase.Running).then(() => {
E
Erich Gamma 已提交
188 189 190 191 192 193
			clearTimeout(timeoutHandle);
		});

		return workbenchContainer;
	}

194
	private onWorkbenchStarted(info: IWorkbenchStartedInfo, instantiationService: IInstantiationService): void {
195

196 197 198 199 200 201 202 203 204 205 206 207 208 209
		// Startup Telemetry
		this.logStartupTelemetry(info);

		// Root Warning
		if ((platform.isLinux || platform.isMacintosh) && process.getuid() === 0) {
			this.messageService.show(Severity.Warning, nls.localize('runningAsRoot', "It is recommended not to run Code as 'root'."));
		}

		// Set lifecycle phase to `Runnning` so that other contributions can now do something
		this.lifecycleService.phase = LifecyclePhase.Running;

		// Set lifecycle phase to `Runnning For A Bit` after a short delay
		let timeoutHandle = setTimeout(() => {
			timeoutHandle = void 0;
B
Benjamin Pasero 已提交
210
			this.lifecycleService.phase = LifecyclePhase.Eventually;
211 212 213 214 215 216 217 218 219 220 221
		}, 3000);
		this.toUnbind.push({
			dispose: () => {
				if (timeoutHandle) {
					clearTimeout(timeoutHandle);
				}
			}
		});
	}

	private logStartupTelemetry(info: IWorkbenchStartedInfo): void {
B
Benjamin Pasero 已提交
222
		const { filesToOpen, filesToCreate, filesToDiff } = this.configuration;
K
kieferrm 已提交
223
		/* __GDPR__
K
kieferrm 已提交
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
			"workspaceLoad" : {
				"userAgent" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.innerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.innerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.outerHeight": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"windowSize.outerWidth": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"emptyWorkbench": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToOpen": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToCreate": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"workbench.filesToDiff": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"customKeybindingsCount": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"theme": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"language": { "classification": "SystemMetaData", "purpose": "BusinessInsight" },
				"experiments": { "${inline}": [ "${IExperiments}" ] },
				"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"restoredViewlet": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"restoredEditors": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"pinnedViewlets": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
				"startupKind": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
			}
		*/
245 246 247
		this.telemetryService.publicLog('workspaceLoad', {
			userAgent: navigator.userAgent,
			windowSize: { innerHeight: window.innerHeight, innerWidth: window.innerWidth, outerHeight: window.outerHeight, outerWidth: window.outerWidth },
248
			emptyWorkbench: this.contextService.getWorkbenchState() === WorkbenchState.EMPTY,
249 250 251
			'workbench.filesToOpen': filesToOpen && filesToOpen.length || 0,
			'workbench.filesToCreate': filesToCreate && filesToCreate.length || 0,
			'workbench.filesToDiff': filesToDiff && filesToDiff.length || 0,
252
			customKeybindingsCount: info.customKeybindingsCount,
B
Benjamin Pasero 已提交
253
			theme: this.themeService.getColorTheme().id,
254
			language: platform.language,
255
			experiments: this.experimentService.getExperiments(),
256 257
			pinnedViewlets: info.pinnedViewlets,
			restoredViewlet: info.restoredViewlet,
258 259
			restoredEditors: info.restoredEditors.length,
			startupKind: this.lifecycleService.startupKind
260 261
		});

B
Benjamin Pasero 已提交
262
		// Telemetry: startup metrics
263
		this.timerService.workbenchStarted = Date.now();
B
Benjamin Pasero 已提交
264 265
		this.timerService.restoreEditorsDuration = info.restoreEditorsDuration;
		this.timerService.restoreViewletDuration = info.restoreViewletDuration;
266
		this.extensionService.whenInstalledExtensionsRegistered().done(() => {
K
kieferrm 已提交
267
			/* __GDPR__
K
kieferrm 已提交
268 269 270 271 272 273
				"startupTime" : {
					"${include}": [
						"${IStartupMetrics}"
					]
				}
			*/
B
Benjamin Pasero 已提交
274
			this.telemetryService.publicLog('startupTime', this.timerService.startupMetrics);
275
		});
B
Benjamin Pasero 已提交
276 277
	}

278
	private initServiceCollection(container: HTMLElement): [IInstantiationService, ServiceCollection] {
J
Johannes Rieken 已提交
279
		const disposables: IDisposable[] = [];
J
Joao Moreno 已提交
280

281 282 283
		const serviceCollection = new ServiceCollection();
		serviceCollection.set(IWorkspaceContextService, this.contextService);
		serviceCollection.set(IConfigurationService, this.configurationService);
284
		serviceCollection.set(IEnvironmentService, this.environmentService);
J
Joao Moreno 已提交
285
		serviceCollection.set(ILogService, this.logService);
286 287
		disposables.push(this.logService);

B
Benjamin Pasero 已提交
288
		serviceCollection.set(ITimerService, this.timerService);
289
		serviceCollection.set(IStorageService, this.storageService);
290 291 292
		this.mainProcessServices.forEach((serviceIdentifier, serviceInstance) => {
			serviceCollection.set(serviceIdentifier, serviceInstance);
		});
293

294
		const instantiationService: IInstantiationService = new InstantiationService(serviceCollection, true);
295

296 297
		this.broadcastService = new BroadcastService(currentWindow.id);
		serviceCollection.set(IBroadcastService, this.broadcastService);
298

299
		serviceCollection.set(IWindowService, new SyncDescriptor(WindowService, currentWindow.id, this.configuration));
J
Joao Moreno 已提交
300

301
		const sharedProcess = (<IWindowsService>serviceCollection.get(IWindowsService)).whenSharedProcessReady()
302
			.then(() => connectNet(this.environmentService.sharedIPCHandle, `window:${currentWindow.id}`));
303 304 305

		sharedProcess
			.done(client => client.registerChannel('choice', instantiationService.createInstance(ChoiceChannel)));
306

307 308
		// Warm up font cache information before building up too many dom elements
		restoreFontInfo(this.storageService);
309
		readFontInfo(BareFontInfo.createFromRawSettings(this.configurationService.getValue('editor'), browser.getZoomLevel()));
310

B
Benjamin Pasero 已提交
311 312 313
		// Hash
		serviceCollection.set(IHashService, new SyncDescriptor(HashService));

314 315 316 317
		// Experiments
		this.experimentService = instantiationService.createInstance(ExperimentService);
		serviceCollection.set(IExperimentService, this.experimentService);

318
		// Telemetry
319
		if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !this.environmentService.args['disable-telemetry'] && !!product.enableTelemetry) {
320
			const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcess.then(c => c.getChannel('telemetryAppender')));
321 322
			const commit = product.commit;
			const version = pkg.version;
323

324
			const config: ITelemetryServiceConfig = {
325
				appender: new TelemetryAppenderClient(channel),
326
				commonProperties: resolveWorkbenchCommonProperties(this.storageService, commit, version, this.configuration.machineId, this.environmentService.installSourcePath),
327
				piiPaths: [this.environmentService.appRoot, this.environmentService.extensionsPath]
328
			};
329

J
Joao Moreno 已提交
330
			const telemetryService = instantiationService.createInstance(TelemetryService, config);
331 332
			this.telemetryService = telemetryService;

J
Joao Moreno 已提交
333
			const errorTelemetry = new ErrorTelemetry(telemetryService);
334 335

			disposables.push(telemetryService, errorTelemetry);
336
		} else {
337
			this.telemetryService = NullTelemetryService;
338
		}
E
Erich Gamma 已提交
339

340
		serviceCollection.set(ITelemetryService, this.telemetryService);
J
Johannes Rieken 已提交
341
		disposables.push(configurationTelemetry(this.telemetryService, this.configurationService));
E
Erich Gamma 已提交
342

343
		let crashReporterService = NullCrashReporterService;
344
		if (!this.environmentService.disableCrashReporter && product.crashReporter && product.hockeyApp) {
345 346 347 348
			crashReporterService = instantiationService.createInstance(CrashReporterService);
		}
		serviceCollection.set(ICrashReporterService, crashReporterService);

349
		this.messageService = instantiationService.createInstance(MessageService, container);
350
		serviceCollection.set(IMessageService, this.messageService);
J
Joao Moreno 已提交
351
		serviceCollection.set(IChoiceService, this.messageService);
E
Erich Gamma 已提交
352

353
		const lifecycleService = instantiationService.createInstance(LifecycleService);
J
Johannes Rieken 已提交
354
		this.toUnbind.push(lifecycleService.onShutdown(reason => dispose(disposables)));
355
		this.toUnbind.push(lifecycleService.onShutdown(reason => saveFontInfo(this.storageService)));
356
		serviceCollection.set(ILifecycleService, lifecycleService);
357
		this.lifecycleService = lifecycleService;
358

S
Sandeep Somavarapu 已提交
359
		const extensionManagementChannel = getDelayedChannel<IExtensionManagementChannel>(sharedProcess.then(c => c.getChannel('extensions')));
360
		serviceCollection.set(IExtensionManagementService, new SyncDescriptor(ExtensionManagementChannelClient, extensionManagementChannel));
S
Sandeep Somavarapu 已提交
361

362 363
		const extensionEnablementService = instantiationService.createInstance(ExtensionEnablementService);
		serviceCollection.set(IExtensionEnablementService, extensionEnablementService);
J
Johannes Rieken 已提交
364
		disposables.push(extensionEnablementService);
365

366
		this.extensionService = instantiationService.createInstance(ExtensionService);
367
		serviceCollection.set(IExtensionService, this.extensionService);
368 369

		this.timerService.beforeExtensionLoad = Date.now();
370
		this.extensionService.whenInstalledExtensionsRegistered().done(() => {
371
			this.timerService.afterExtensionLoad = Date.now();
372
		});
E
Erich Gamma 已提交
373

B
Benjamin Pasero 已提交
374 375 376
		this.themeService = instantiationService.createInstance(WorkbenchThemeService, document.body);
		serviceCollection.set(IWorkbenchThemeService, this.themeService);

377
		serviceCollection.set(ICommandService, new SyncDescriptor(CommandService));
378

379 380
		this.contextViewService = instantiationService.createInstance(ContextViewService, this.container);
		serviceCollection.set(IContextViewService, this.contextViewService);
E
Erich Gamma 已提交
381

382
		serviceCollection.set(IRequestService, new SyncDescriptor(RequestService));
E
Erich Gamma 已提交
383

384
		serviceCollection.set(IMarkerService, new SyncDescriptor(MarkerService));
E
Erich Gamma 已提交
385

386
		serviceCollection.set(IModeService, new SyncDescriptor(WorkbenchModeServiceImpl));
387

388
		serviceCollection.set(IModelService, new SyncDescriptor(ModelServiceImpl));
389

390 391
		serviceCollection.set(ITextResourceConfigurationService, new SyncDescriptor(TextResourceConfigurationService));

392
		serviceCollection.set(IEditorWorkerService, new SyncDescriptor(EditorWorkerServiceImpl));
393

394
		serviceCollection.set(IUntitledEditorService, new SyncDescriptor(UntitledEditorService));
395

396
		serviceCollection.set(ITextMateService, new SyncDescriptor(TextMateService));
A
Alex Dima 已提交
397

398
		serviceCollection.set(ISearchService, new SyncDescriptor(SearchService));
399

400
		serviceCollection.set(ICodeEditorService, new SyncDescriptor(CodeEditorServiceImpl));
401

402
		serviceCollection.set(IIntegrityService, new SyncDescriptor(IntegrityServiceImpl));
A
Alex Dima 已提交
403

404
		return [instantiationService, serviceCollection];
E
Erich Gamma 已提交
405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436
	}

	public open(): void {

		// Listen on unexpected errors
		errors.setUnexpectedErrorHandler((error: any) => {
			this.onUnexpectedError(error);
		});

		// Shell Class for CSS Scoping
		$(this.container).addClass('monaco-shell');

		// Controls
		this.content = $('.monaco-shell-content').appendTo(this.container).getHTMLElement();

		// Create Contents
		this.contentsContainer = this.createContents($(this.content));

		// Layout
		this.layout();

		// Listeners
		this.registerListeners();
	}

	private registerListeners(): void {

		// Resize
		$(window).on(dom.EventType.RESIZE, () => this.layout(), this.toUnbind);
	}

	public onUnexpectedError(error: any): void {
437
		const errorMsg = toErrorMessage(error, true);
E
Erich Gamma 已提交
438 439 440 441
		if (!errorMsg) {
			return;
		}

442
		const now = Date.now();
E
Erich Gamma 已提交
443 444 445 446 447 448 449
		if (errorMsg === this.previousErrorValue && now - this.previousErrorTime <= 1000) {
			return; // Return if error message identical to previous and shorter than 1 second
		}

		this.previousErrorTime = now;
		this.previousErrorValue = errorMsg;

450
		// Log it
451
		this.logService.error(errorMsg);
E
Erich Gamma 已提交
452 453

		// Show to user if friendly message provided
454
		if (error && error.friendlyMessage && this.messageService) {
B
Benjamin Pasero 已提交
455
			this.messageService.show(Severity.Error, error.friendlyMessage);
E
Erich Gamma 已提交
456 457 458
		}
	}

B
Benjamin Pasero 已提交
459
	private layout(): void {
460
		const clArea = $(this.container).getClientArea();
E
Erich Gamma 已提交
461

462
		const contentsSize = new Dimension(clArea.width, clArea.height);
E
Erich Gamma 已提交
463 464
		this.contentsContainer.size(contentsSize.width, contentsSize.height);

B
Benjamin Pasero 已提交
465
		this.contextViewService.layout();
E
Erich Gamma 已提交
466 467 468
		this.workbench.layout();
	}

B
Benjamin Pasero 已提交
469
	public dispose(): void {
E
Erich Gamma 已提交
470 471 472

		// Workbench
		if (this.workbench) {
B
Benjamin Pasero 已提交
473
			this.workbench.dispose();
E
Erich Gamma 已提交
474 475
		}

B
Benjamin Pasero 已提交
476
		this.contextViewService.dispose();
E
Erich Gamma 已提交
477 478

		// Listeners
J
Joao Moreno 已提交
479
		this.toUnbind = dispose(this.toUnbind);
E
Erich Gamma 已提交
480 481 482 483

		// Container
		$(this.container).empty();
	}
484
}
485 486

registerThemingParticipant((theme: ITheme, collector: ICssStyleCollector) => {
B
Benjamin Pasero 已提交
487 488

	// Foreground
B
Benjamin Pasero 已提交
489
	const windowForeground = theme.getColor(foreground);
490 491 492
	if (windowForeground) {
		collector.addRule(`.monaco-shell { color: ${windowForeground}; }`);
	}
B
Benjamin Pasero 已提交
493

494 495 496 497 498 499
	// Selection
	const windowSelectionBackground = theme.getColor(selectionBackground);
	if (windowSelectionBackground) {
		collector.addRule(`.monaco-shell ::selection { background-color: ${windowSelectionBackground}; }`);
	}

500 501 502 503 504 505 506
	// Input placeholder
	const placeholderForeground = theme.getColor(inputPlaceholderForeground);
	if (placeholderForeground) {
		collector.addRule(`.monaco-shell input::-webkit-input-placeholder { color: ${placeholderForeground}; }`);
		collector.addRule(`.monaco-shell textarea::-webkit-input-placeholder { color: ${placeholderForeground}; }`);
	}

507 508 509 510 511 512 513 514 515 516 517
	// List highlight
	const listHighlightForegroundColor = theme.getColor(listHighlightForeground);
	if (listHighlightForegroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-tree .monaco-tree-row .monaco-highlighted-label .highlight,
			.monaco-shell .monaco-list .monaco-list-row .monaco-highlighted-label .highlight {
				color: ${listHighlightForegroundColor};
			}
		`);
	}

B
Benjamin Pasero 已提交
518
	// We need to set the workbench background color so that on Windows we get subpixel-antialiasing.
519 520 521 522 523 524 525 526 527 528 529 530 531
	let workbenchBackground: string;
	switch (theme.type) {
		case 'dark':
			workbenchBackground = '#252526';
			break;
		case 'light':
			workbenchBackground = '#F3F3F3';
			break;
		default:
			workbenchBackground = '#000000';
	}
	collector.addRule(`.monaco-workbench { background-color: ${workbenchBackground}; }`);

B
Benjamin Pasero 已提交
532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
	// Scrollbars
	const scrollbarShadowColor = theme.getColor(scrollbarShadow);
	if (scrollbarShadowColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .shadow.top {
				box-shadow: ${scrollbarShadowColor} 0 6px 6px -6px inset;
			}

			.monaco-shell .monaco-scrollable-element > .shadow.left {
				box-shadow: ${scrollbarShadowColor} 6px 0 6px -6px inset;
			}

			.monaco-shell .monaco-scrollable-element > .shadow.top.left {
				box-shadow: ${scrollbarShadowColor} 6px 6px 6px -6px inset;
			}
		`);
	}

	const scrollbarSliderBackgroundColor = theme.getColor(scrollbarSliderBackground);
	if (scrollbarSliderBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider {
				background: ${scrollbarSliderBackgroundColor};
			}
		`);
	}

	const scrollbarSliderHoverBackgroundColor = theme.getColor(scrollbarSliderHoverBackground);
	if (scrollbarSliderHoverBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider:hover {
				background: ${scrollbarSliderHoverBackgroundColor};
			}
		`);
	}

	const scrollbarSliderActiveBackgroundColor = theme.getColor(scrollbarSliderActiveBackground);
	if (scrollbarSliderActiveBackgroundColor) {
		collector.addRule(`
			.monaco-shell .monaco-scrollable-element > .scrollbar > .slider.active {
				background: ${scrollbarSliderActiveBackgroundColor};
			}
		`);
	}

	// Focus outline
578
	const focusOutline = theme.getColor(focusBorder);
B
Benjamin Pasero 已提交
579 580 581 582 583 584 585 586
	if (focusOutline) {
		collector.addRule(`
			.monaco-shell [tabindex="0"]:focus,
			.monaco-shell .synthetic-focus,
			.monaco-shell select:focus,
			.monaco-shell .monaco-tree.focused.no-focused-item:focus:before,
			.monaco-shell input[type="button"]:focus,
			.monaco-shell input[type="text"]:focus,
B
Benjamin Pasero 已提交
587
			.monaco-shell button:focus,
B
Benjamin Pasero 已提交
588 589 590 591 592 593 594
			.monaco-shell textarea:focus,
			.monaco-shell input[type="search"]:focus,
			.monaco-shell input[type="checkbox"]:focus {
				outline-color: ${focusOutline};
			}
		`);
	}
595
});