1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var __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 | };
|
23 | var __metadata = (this && this.__metadata) || function (k, v) {
|
24 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
25 | };
|
26 | var __param = (this && this.__param) || function (paramIndex, decorator) {
|
27 | return function (target, key) { decorator(target, key, paramIndex); }
|
28 | };
|
29 | Object.defineProperty(exports, "__esModule", { value: true });
|
30 | exports.FrontendApplication = exports.DefaultFrontendApplicationContribution = exports.OnWillStopAction = exports.FrontendApplicationContribution = void 0;
|
31 | const inversify_1 = require("inversify");
|
32 | const common_1 = require("../common");
|
33 | const keybinding_1 = require("./keybinding");
|
34 | const widgets_1 = require("./widgets");
|
35 | const application_shell_1 = require("./shell/application-shell");
|
36 | const shell_layout_restorer_1 = require("./shell/shell-layout-restorer");
|
37 | const frontend_application_state_1 = require("./frontend-application-state");
|
38 | const browser_1 = require("./browser");
|
39 | const core_preferences_1 = require("./core-preferences");
|
40 | const window_service_1 = require("./window/window-service");
|
41 | const tooltip_service_1 = require("./tooltip-service");
|
42 |
|
43 |
|
44 |
|
45 | exports.FrontendApplicationContribution = Symbol('FrontendApplicationContribution');
|
46 | var OnWillStopAction;
|
47 | (function (OnWillStopAction) {
|
48 | function is(candidate) {
|
49 | return (0, common_1.isObject)(candidate) && 'action' in candidate && 'reason' in candidate;
|
50 | }
|
51 | OnWillStopAction.is = is;
|
52 | })(OnWillStopAction = exports.OnWillStopAction || (exports.OnWillStopAction = {}));
|
53 | const TIMER_WARNING_THRESHOLD = 100;
|
54 |
|
55 |
|
56 |
|
57 |
|
58 | let DefaultFrontendApplicationContribution = class DefaultFrontendApplicationContribution {
|
59 | initialize() {
|
60 |
|
61 | }
|
62 | };
|
63 | DefaultFrontendApplicationContribution = __decorate([
|
64 | (0, inversify_1.injectable)()
|
65 | ], DefaultFrontendApplicationContribution);
|
66 | exports.DefaultFrontendApplicationContribution = DefaultFrontendApplicationContribution;
|
67 | let FrontendApplication = class FrontendApplication {
|
68 | constructor(commands, menus, keybindings, layoutRestorer, contributions, _shell, stateService) {
|
69 | this.commands = commands;
|
70 | this.menus = menus;
|
71 | this.keybindings = keybindings;
|
72 | this.layoutRestorer = layoutRestorer;
|
73 | this.contributions = contributions;
|
74 | this._shell = _shell;
|
75 | this.stateService = stateService;
|
76 | }
|
77 | get shell() {
|
78 | return this._shell;
|
79 | }
|
80 | |
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 | async start() {
|
90 | const startup = this.backendStopwatch.start('frontend');
|
91 | await this.measure('startContributions', () => this.startContributions(), 'Start frontend contributions', false);
|
92 | this.stateService.state = 'started_contributions';
|
93 | const host = await this.getHost();
|
94 | this.attachShell(host);
|
95 | this.attachTooltip(host);
|
96 | await (0, browser_1.animationFrame)();
|
97 | this.stateService.state = 'attached_shell';
|
98 | await this.measure('initializeLayout', () => this.initializeLayout(), 'Initialize the workbench layout', false);
|
99 | this.stateService.state = 'initialized_layout';
|
100 | await this.fireOnDidInitializeLayout();
|
101 | await this.measure('revealShell', () => this.revealShell(host), 'Replace loading indicator with ready workbench UI (animation)', false);
|
102 | this.registerEventListeners();
|
103 | this.stateService.state = 'ready';
|
104 | startup.then(idToken => this.backendStopwatch.stop(idToken, 'Frontend application start', []));
|
105 | }
|
106 | |
107 |
|
108 |
|
109 | getHost() {
|
110 | if (document.body) {
|
111 | return Promise.resolve(document.body);
|
112 | }
|
113 | return new Promise(resolve => window.addEventListener('load', () => resolve(document.body), { once: true }));
|
114 | }
|
115 | |
116 |
|
117 |
|
118 | getStartupIndicator(host) {
|
119 | const startupElements = host.getElementsByClassName('theia-preload');
|
120 | return startupElements.length === 0 ? undefined : startupElements[0];
|
121 | }
|
122 | |
123 |
|
124 |
|
125 | registerEventListeners() {
|
126 | this.windowsService.onUnload(() => {
|
127 | this.stateService.state = 'closing_window';
|
128 | this.layoutRestorer.storeLayout(this);
|
129 | this.stopContributions();
|
130 | });
|
131 | window.addEventListener('resize', () => this.shell.update());
|
132 | this.keybindings.registerEventListeners(window);
|
133 | document.addEventListener('touchmove', event => { event.preventDefault(); }, { passive: false });
|
134 |
|
135 | if (common_1.isOSX) {
|
136 | document.body.addEventListener('wheel', browser_1.preventNavigation, { passive: false });
|
137 | }
|
138 |
|
139 | document.addEventListener('dragenter', event => {
|
140 | if (event.dataTransfer) {
|
141 | event.dataTransfer.dropEffect = 'none';
|
142 | }
|
143 | event.preventDefault();
|
144 | }, false);
|
145 | document.addEventListener('dragover', event => {
|
146 | if (event.dataTransfer) {
|
147 | event.dataTransfer.dropEffect = 'none';
|
148 | }
|
149 | event.preventDefault();
|
150 | }, false);
|
151 | document.addEventListener('drop', event => {
|
152 | event.preventDefault();
|
153 | }, false);
|
154 | }
|
155 | |
156 |
|
157 |
|
158 |
|
159 | attachShell(host) {
|
160 | const ref = this.getStartupIndicator(host);
|
161 | widgets_1.Widget.attach(this.shell, host, ref);
|
162 | }
|
163 | |
164 |
|
165 |
|
166 | attachTooltip(host) {
|
167 | this.tooltipService.attachTo(host);
|
168 | }
|
169 | |
170 |
|
171 |
|
172 |
|
173 | revealShell(host) {
|
174 | const startupElem = this.getStartupIndicator(host);
|
175 | if (startupElem) {
|
176 | return new Promise(resolve => {
|
177 | window.requestAnimationFrame(() => {
|
178 | startupElem.classList.add('theia-hidden');
|
179 | const preloadStyle = window.getComputedStyle(startupElem);
|
180 | const transitionDuration = (0, browser_1.parseCssTime)(preloadStyle.transitionDuration, 0);
|
181 | window.setTimeout(() => {
|
182 | const parent = startupElem.parentElement;
|
183 | if (parent) {
|
184 | parent.removeChild(startupElem);
|
185 | }
|
186 | resolve();
|
187 | }, transitionDuration);
|
188 | });
|
189 | });
|
190 | }
|
191 | else {
|
192 | return Promise.resolve();
|
193 | }
|
194 | }
|
195 | |
196 |
|
197 |
|
198 |
|
199 | async initializeLayout() {
|
200 | if (!await this.restoreLayout()) {
|
201 |
|
202 | await this.createDefaultLayout();
|
203 | }
|
204 | await this.shell.pendingUpdates;
|
205 | }
|
206 | |
207 |
|
208 |
|
209 | async restoreLayout() {
|
210 | try {
|
211 | return await this.layoutRestorer.restoreLayout(this);
|
212 | }
|
213 | catch (error) {
|
214 | if (shell_layout_restorer_1.ApplicationShellLayoutMigrationError.is(error)) {
|
215 | console.warn(error.message);
|
216 | console.info('Initializing the default layout instead...');
|
217 | }
|
218 | else {
|
219 | console.error('Could not restore layout', error);
|
220 | }
|
221 | return false;
|
222 | }
|
223 | }
|
224 | |
225 |
|
226 |
|
227 |
|
228 | async createDefaultLayout() {
|
229 | for (const contribution of this.contributions.getContributions()) {
|
230 | if (contribution.initializeLayout) {
|
231 | await this.measure(contribution.constructor.name + '.initializeLayout', () => contribution.initializeLayout(this));
|
232 | }
|
233 | }
|
234 | }
|
235 | async fireOnDidInitializeLayout() {
|
236 | for (const contribution of this.contributions.getContributions()) {
|
237 | if (contribution.onDidInitializeLayout) {
|
238 | await this.measure(contribution.constructor.name + '.onDidInitializeLayout', () => contribution.onDidInitializeLayout(this));
|
239 | }
|
240 | }
|
241 | }
|
242 | |
243 |
|
244 |
|
245 | async startContributions() {
|
246 | for (const contribution of this.contributions.getContributions()) {
|
247 | if (contribution.initialize) {
|
248 | try {
|
249 | await this.measure(contribution.constructor.name + '.initialize', () => contribution.initialize());
|
250 | }
|
251 | catch (error) {
|
252 | console.error('Could not initialize contribution', error);
|
253 | }
|
254 | }
|
255 | }
|
256 | for (const contribution of this.contributions.getContributions()) {
|
257 | if (contribution.configure) {
|
258 | try {
|
259 | await this.measure(contribution.constructor.name + '.configure', () => contribution.configure(this));
|
260 | }
|
261 | catch (error) {
|
262 | console.error('Could not configure contribution', error);
|
263 | }
|
264 | }
|
265 | }
|
266 | |
267 |
|
268 |
|
269 |
|
270 |
|
271 | await this.measure('commands.onStart', () => this.commands.onStart());
|
272 | await this.measure('keybindings.onStart', () => this.keybindings.onStart());
|
273 | await this.measure('menus.onStart', () => this.menus.onStart());
|
274 | for (const contribution of this.contributions.getContributions()) {
|
275 | if (contribution.onStart) {
|
276 | try {
|
277 | await this.measure(contribution.constructor.name + '.onStart', () => contribution.onStart(this));
|
278 | }
|
279 | catch (error) {
|
280 | console.error('Could not start contribution', error);
|
281 | }
|
282 | }
|
283 | }
|
284 | }
|
285 | |
286 |
|
287 |
|
288 | stopContributions() {
|
289 | console.info('>>> Stopping frontend contributions...');
|
290 | for (const contribution of this.contributions.getContributions()) {
|
291 | if (contribution.onStop) {
|
292 | try {
|
293 | contribution.onStop(this);
|
294 | }
|
295 | catch (error) {
|
296 | console.error('Could not stop contribution', error);
|
297 | }
|
298 | }
|
299 | }
|
300 | console.info('<<< All frontend contributions have been stopped.');
|
301 | }
|
302 | async measure(name, fn, message = `Frontend ${name}`, threshold = true) {
|
303 | return this.stopwatch.startAsync(name, message, fn, threshold ? { thresholdMillis: TIMER_WARNING_THRESHOLD, defaultLogLevel: common_1.LogLevel.DEBUG } : {});
|
304 | }
|
305 | };
|
306 | __decorate([
|
307 | (0, inversify_1.inject)(core_preferences_1.CorePreferences),
|
308 | __metadata("design:type", Object)
|
309 | ], FrontendApplication.prototype, "corePreferences", void 0);
|
310 | __decorate([
|
311 | (0, inversify_1.inject)(window_service_1.WindowService),
|
312 | __metadata("design:type", Object)
|
313 | ], FrontendApplication.prototype, "windowsService", void 0);
|
314 | __decorate([
|
315 | (0, inversify_1.inject)(tooltip_service_1.TooltipService),
|
316 | __metadata("design:type", Object)
|
317 | ], FrontendApplication.prototype, "tooltipService", void 0);
|
318 | __decorate([
|
319 | (0, inversify_1.inject)(common_1.Stopwatch),
|
320 | __metadata("design:type", common_1.Stopwatch)
|
321 | ], FrontendApplication.prototype, "stopwatch", void 0);
|
322 | __decorate([
|
323 | (0, inversify_1.inject)(common_1.BackendStopwatch),
|
324 | __metadata("design:type", Object)
|
325 | ], FrontendApplication.prototype, "backendStopwatch", void 0);
|
326 | FrontendApplication = __decorate([
|
327 | (0, inversify_1.injectable)(),
|
328 | __param(0, (0, inversify_1.inject)(common_1.CommandRegistry)),
|
329 | __param(1, (0, inversify_1.inject)(common_1.MenuModelRegistry)),
|
330 | __param(2, (0, inversify_1.inject)(keybinding_1.KeybindingRegistry)),
|
331 | __param(3, (0, inversify_1.inject)(shell_layout_restorer_1.ShellLayoutRestorer)),
|
332 | __param(4, (0, inversify_1.inject)(common_1.ContributionProvider)),
|
333 | __param(4, (0, inversify_1.named)(exports.FrontendApplicationContribution)),
|
334 | __param(5, (0, inversify_1.inject)(application_shell_1.ApplicationShell)),
|
335 | __param(6, (0, inversify_1.inject)(frontend_application_state_1.FrontendApplicationStateService)),
|
336 | __metadata("design:paramtypes", [common_1.CommandRegistry,
|
337 | common_1.MenuModelRegistry,
|
338 | keybinding_1.KeybindingRegistry,
|
339 | shell_layout_restorer_1.ShellLayoutRestorer, Object, application_shell_1.ApplicationShell,
|
340 | frontend_application_state_1.FrontendApplicationStateService])
|
341 | ], FrontendApplication);
|
342 | exports.FrontendApplication = FrontendApplication;
|
343 |
|
\ | No newline at end of file |