@theia/core 1.50.1 → 1.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/i18n/nls.cs.json +4 -7
- package/i18n/nls.de.json +4 -7
- package/i18n/nls.es.json +4 -7
- package/i18n/nls.fr.json +4 -7
- package/i18n/nls.hu.json +4 -7
- package/i18n/nls.it.json +4 -7
- package/i18n/nls.ja.json +4 -7
- package/i18n/nls.json +4 -7
- package/i18n/nls.pl.json +4 -7
- package/i18n/nls.pt-br.json +4 -7
- package/i18n/nls.pt-pt.json +4 -7
- package/i18n/nls.ru.json +4 -7
- package/i18n/nls.zh-cn.json +4 -7
- package/lib/browser/authentication-service.d.ts +6 -3
- package/lib/browser/authentication-service.d.ts.map +1 -1
- package/lib/browser/authentication-service.js +11 -1
- package/lib/browser/authentication-service.js.map +1 -1
- package/lib/browser/browser.d.ts +6 -1
- package/lib/browser/browser.d.ts.map +1 -1
- package/lib/browser/browser.js +7 -2
- package/lib/browser/browser.js.map +1 -1
- package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/common-frontend-contribution.js +6 -5
- package/lib/browser/common-frontend-contribution.js.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +3 -3
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/http-open-handler.d.ts +1 -0
- package/lib/browser/http-open-handler.d.ts.map +1 -1
- package/lib/browser/http-open-handler.js +5 -3
- package/lib/browser/http-open-handler.js.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts +2 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +22 -19
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/messaging/service-connection-provider.d.ts +15 -1
- package/lib/browser/messaging/service-connection-provider.d.ts.map +1 -1
- package/lib/browser/messaging/service-connection-provider.js +15 -1
- package/lib/browser/messaging/service-connection-provider.js.map +1 -1
- package/lib/browser/saveable.d.ts +14 -1
- package/lib/browser/saveable.d.ts.map +1 -1
- package/lib/browser/saveable.js +10 -1
- package/lib/browser/saveable.js.map +1 -1
- package/lib/browser/shell/additional-views-menu-widget.d.ts +2 -2
- package/lib/browser/shell/additional-views-menu-widget.d.ts.map +1 -1
- package/lib/browser/shell/additional-views-menu-widget.js +8 -4
- package/lib/browser/shell/additional-views-menu-widget.js.map +1 -1
- package/lib/browser/shell/application-shell.d.ts +7 -2
- package/lib/browser/shell/application-shell.d.ts.map +1 -1
- package/lib/browser/shell/application-shell.js +14 -1
- package/lib/browser/shell/application-shell.js.map +1 -1
- package/lib/browser/shell/side-panel-handler.d.ts.map +1 -1
- package/lib/browser/shell/side-panel-handler.js +2 -1
- package/lib/browser/shell/side-panel-handler.js.map +1 -1
- package/lib/browser/shell/sidebar-menu-widget.d.ts +14 -1
- package/lib/browser/shell/sidebar-menu-widget.d.ts.map +1 -1
- package/lib/browser/shell/sidebar-menu-widget.js +51 -13
- package/lib/browser/shell/sidebar-menu-widget.js.map +1 -1
- package/lib/browser/shell/split-panels.d.ts +1 -1
- package/lib/browser/shell/split-panels.d.ts.map +1 -1
- package/lib/browser/shell/split-panels.js +4 -3
- package/lib/browser/shell/split-panels.js.map +1 -1
- package/lib/browser/shell/tab-bars.d.ts +5 -4
- package/lib/browser/shell/tab-bars.d.ts.map +1 -1
- package/lib/browser/shell/tab-bars.js +41 -52
- package/lib/browser/shell/tab-bars.js.map +1 -1
- package/lib/browser/shell/theia-dock-panel.d.ts +7 -1
- package/lib/browser/shell/theia-dock-panel.d.ts.map +1 -1
- package/lib/browser/shell/theia-dock-panel.js +5 -1
- package/lib/browser/shell/theia-dock-panel.js.map +1 -1
- package/lib/browser/widget-manager.d.ts +2 -1
- package/lib/browser/widget-manager.d.ts.map +1 -1
- package/lib/browser/widget-manager.js +16 -9
- package/lib/browser/widget-manager.js.map +1 -1
- package/lib/browser/widget-open-handler.js +1 -1
- package/lib/browser/widget-open-handler.js.map +1 -1
- package/lib/browser/widgets/react-renderer.d.ts.map +1 -1
- package/lib/browser/widgets/react-renderer.js +4 -1
- package/lib/browser/widgets/react-renderer.js.map +1 -1
- package/lib/browser-only/frontend-only-application-module.d.ts.map +1 -1
- package/lib/browser-only/frontend-only-application-module.js +1 -0
- package/lib/browser-only/frontend-only-application-module.js.map +1 -1
- package/lib/common/application-protocol.d.ts +1 -0
- package/lib/common/application-protocol.d.ts.map +1 -1
- package/lib/common/menu/menu-model-registry.d.ts +6 -0
- package/lib/common/menu/menu-model-registry.d.ts.map +1 -1
- package/lib/common/menu/menu-model-registry.js +31 -5
- package/lib/common/menu/menu-model-registry.js.map +1 -1
- package/lib/common/preferences/preference-schema.d.ts +6 -0
- package/lib/common/preferences/preference-schema.d.ts.map +1 -1
- package/lib/common/preferences/preference-schema.js.map +1 -1
- package/lib/common/quick-pick-service.d.ts +0 -9
- package/lib/common/quick-pick-service.d.ts.map +1 -1
- package/lib/common/quick-pick-service.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +3 -0
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/preload.js +3 -3
- package/lib/electron-browser/preload.js.map +1 -1
- package/lib/electron-browser/window/electron-window-module.d.ts.map +1 -1
- package/lib/electron-browser/window/electron-window-module.js +11 -7
- package/lib/electron-browser/window/electron-window-module.js.map +1 -1
- package/lib/electron-browser/window/electron-window-service.js +1 -1
- package/lib/electron-browser/window/electron-window-service.js.map +1 -1
- package/lib/electron-browser/window/external-app-open-handler.d.ts +12 -0
- package/lib/electron-browser/window/external-app-open-handler.d.ts.map +1 -0
- package/lib/electron-browser/window/external-app-open-handler.js +42 -0
- package/lib/electron-browser/window/external-app-open-handler.js.map +1 -0
- package/lib/electron-common/electron-api.d.ts +5 -2
- package/lib/electron-common/electron-api.d.ts.map +1 -1
- package/lib/electron-common/electron-api.js.map +1 -1
- package/lib/electron-main/electron-main-application.d.ts +1 -2
- package/lib/electron-main/electron-main-application.d.ts.map +1 -1
- package/lib/electron-main/electron-main-application.js +66 -32
- package/lib/electron-main/electron-main-application.js.map +1 -1
- package/lib/electron-main/electron-main-constants.d.ts +1 -0
- package/lib/electron-main/electron-main-constants.d.ts.map +1 -1
- package/lib/electron-main/theia-electron-window.d.ts +1 -1
- package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
- package/lib/electron-main/theia-electron-window.js +8 -3
- package/lib/electron-main/theia-electron-window.js.map +1 -1
- package/lib/node/application-server.d.ts +1 -0
- package/lib/node/application-server.d.ts.map +1 -1
- package/lib/node/application-server.js +3 -0
- package/lib/node/application-server.js.map +1 -1
- package/lib/node/messaging/websocket-frontend-connection-service.d.ts +1 -0
- package/lib/node/messaging/websocket-frontend-connection-service.d.ts.map +1 -1
- package/lib/node/messaging/websocket-frontend-connection-service.js +8 -1
- package/lib/node/messaging/websocket-frontend-connection-service.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/authentication-service.ts +16 -4
- package/src/browser/browser.ts +6 -1
- package/src/browser/common-frontend-contribution.ts +9 -7
- package/src/browser/frontend-application-module.ts +6 -5
- package/src/browser/http-open-handler.ts +3 -1
- package/src/browser/menu/browser-menu-plugin.ts +27 -20
- package/src/browser/messaging/service-connection-provider.ts +15 -1
- package/src/browser/saveable.ts +17 -1
- package/src/browser/shell/additional-views-menu-widget.tsx +5 -5
- package/src/browser/shell/application-shell.ts +21 -4
- package/src/browser/shell/side-panel-handler.ts +2 -1
- package/src/browser/shell/sidebar-menu-widget.tsx +63 -20
- package/src/browser/shell/split-panels.ts +4 -3
- package/src/browser/shell/tab-bars.ts +40 -57
- package/src/browser/shell/theia-dock-panel.ts +13 -3
- package/src/browser/style/sidepanel.css +6 -3
- package/src/browser/style/tabs.css +12 -1
- package/src/browser/widget-manager.ts +19 -11
- package/src/browser/widget-open-handler.ts +3 -3
- package/src/browser/widgets/react-renderer.tsx +4 -1
- package/src/browser-only/frontend-only-application-module.ts +1 -0
- package/src/common/application-protocol.ts +1 -0
- package/src/common/menu/menu-model-registry.ts +36 -5
- package/src/common/preferences/preference-schema.ts +6 -0
- package/src/common/quick-pick-service.ts +0 -3
- package/src/electron-browser/menu/electron-main-menu-factory.ts +3 -0
- package/src/electron-browser/preload.ts +3 -3
- package/src/electron-browser/window/electron-window-module.ts +11 -7
- package/src/electron-browser/window/electron-window-service.ts +1 -1
- package/src/electron-browser/window/external-app-open-handler.ts +42 -0
- package/src/electron-common/electron-api.ts +6 -2
- package/src/electron-main/electron-main-application.ts +76 -35
- package/src/electron-main/electron-main-constants.ts +4 -3
- package/src/electron-main/theia-electron-window.ts +7 -3
- package/src/node/application-server.ts +4 -0
- package/src/node/messaging/websocket-frontend-connection-service.ts +11 -1
|
@@ -133,6 +133,7 @@ export interface AuthenticationService {
|
|
|
133
133
|
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation>;
|
|
134
134
|
|
|
135
135
|
readonly onDidChangeSessions: Event<{ providerId: string, label: string, event: AuthenticationProviderAuthenticationSessionsChangeEvent }>;
|
|
136
|
+
readonly onDidUpdateSignInCount: Event<number>;
|
|
136
137
|
getSessions(providerId: string, scopes?: string[]): Promise<ReadonlyArray<AuthenticationSession>>;
|
|
137
138
|
getLabel(providerId: string): string;
|
|
138
139
|
supportsMultipleAccounts(providerId: string): boolean;
|
|
@@ -157,15 +158,18 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
157
158
|
|
|
158
159
|
protected authenticationProviders: Map<string, AuthenticationProvider> = new Map<string, AuthenticationProvider>();
|
|
159
160
|
|
|
160
|
-
private onDidRegisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
161
|
+
private readonly onDidRegisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
161
162
|
readonly onDidRegisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidRegisterAuthenticationProviderEmitter.event;
|
|
162
163
|
|
|
163
|
-
private onDidUnregisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
164
|
+
private readonly onDidUnregisterAuthenticationProviderEmitter: Emitter<AuthenticationProviderInformation> = new Emitter<AuthenticationProviderInformation>();
|
|
164
165
|
readonly onDidUnregisterAuthenticationProvider: Event<AuthenticationProviderInformation> = this.onDidUnregisterAuthenticationProviderEmitter.event;
|
|
165
166
|
|
|
166
|
-
private onDidChangeSessionsEmitter: Emitter<SessionChangeEvent> = new Emitter<SessionChangeEvent>();
|
|
167
|
+
private readonly onDidChangeSessionsEmitter: Emitter<SessionChangeEvent> = new Emitter<SessionChangeEvent>();
|
|
167
168
|
readonly onDidChangeSessions: Event<SessionChangeEvent> = this.onDidChangeSessionsEmitter.event;
|
|
168
169
|
|
|
170
|
+
private readonly onDidChangeSignInCountEmitter: Emitter<number> = new Emitter<number>();
|
|
171
|
+
readonly onDidUpdateSignInCount: Event<number> = this.onDidChangeSignInCountEmitter.event;
|
|
172
|
+
|
|
169
173
|
@inject(MenuModelRegistry) protected readonly menus: MenuModelRegistry;
|
|
170
174
|
@inject(CommandRegistry) protected readonly commands: CommandRegistry;
|
|
171
175
|
@inject(StorageService) protected readonly storageService: StorageService;
|
|
@@ -295,6 +299,7 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
295
299
|
return;
|
|
296
300
|
}
|
|
297
301
|
|
|
302
|
+
const previousSize = this.signInRequestItems.size;
|
|
298
303
|
const sessions = await provider.getSessions();
|
|
299
304
|
Object.keys(existingRequestsForProvider).forEach(requestedScopes => {
|
|
300
305
|
if (sessions.some(session => session.scopes.slice().sort().join('') === requestedScopes)) {
|
|
@@ -311,6 +316,9 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
311
316
|
}
|
|
312
317
|
}
|
|
313
318
|
});
|
|
319
|
+
if (previousSize !== this.signInRequestItems.size) {
|
|
320
|
+
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
321
|
+
}
|
|
314
322
|
}
|
|
315
323
|
|
|
316
324
|
async requestNewSession(providerId: string, scopes: string[], extensionId: string, extensionName: string): Promise<void> {
|
|
@@ -341,7 +349,7 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
341
349
|
}
|
|
342
350
|
|
|
343
351
|
const menuItem = this.menus.registerMenuAction(ACCOUNTS_SUBMENU, {
|
|
344
|
-
label:
|
|
352
|
+
label: nls.localizeByDefault('Sign in with {0} to use {1} (1)', provider.label, extensionName),
|
|
345
353
|
order: '1',
|
|
346
354
|
commandId: `${extensionId}signIn`,
|
|
347
355
|
});
|
|
@@ -362,6 +370,7 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
362
370
|
}
|
|
363
371
|
});
|
|
364
372
|
|
|
373
|
+
const previousSize = this.signInRequestItems.size;
|
|
365
374
|
if (providerRequests) {
|
|
366
375
|
const existingRequest = providerRequests[scopesList] || { disposables: [], requestingExtensionIds: [] };
|
|
367
376
|
|
|
@@ -378,6 +387,9 @@ export class AuthenticationServiceImpl implements AuthenticationService {
|
|
|
378
387
|
}
|
|
379
388
|
});
|
|
380
389
|
}
|
|
390
|
+
if (previousSize !== this.signInRequestItems.size) {
|
|
391
|
+
this.onDidChangeSignInCountEmitter.fire(this.signInRequestItems.size);
|
|
392
|
+
}
|
|
381
393
|
}
|
|
382
394
|
}
|
|
383
395
|
|
package/src/browser/browser.ts
CHANGED
|
@@ -34,9 +34,14 @@ export const isSafari = (userAgent.indexOf('Chrome') === -1) && (userAgent.index
|
|
|
34
34
|
export const isIPad = (userAgent.indexOf('iPad') >= 0);
|
|
35
35
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
36
|
/**
|
|
37
|
-
* @deprecated
|
|
37
|
+
* @deprecated use Environment.electron.is
|
|
38
38
|
*/
|
|
39
39
|
export const isNative = environment.electron.is();
|
|
40
|
+
/**
|
|
41
|
+
* Determines whether the backend is running in a remote environment.
|
|
42
|
+
* I.e. we use the browser version or connect to a remote Theia instance in Electron.
|
|
43
|
+
*/
|
|
44
|
+
export const isRemote = !environment.electron.is() || new URL(location.href).searchParams.has('localPort');
|
|
40
45
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
46
|
export const isBasicWasmSupported = typeof (window as any).WebAssembly !== 'undefined';
|
|
42
47
|
|
|
@@ -61,11 +61,12 @@ import { ConfirmDialog, confirmExit, ConfirmSaveDialog, Dialog } from './dialogs
|
|
|
61
61
|
import { WindowService } from './window/window-service';
|
|
62
62
|
import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
|
|
63
63
|
import { DecorationStyle } from './decoration-style';
|
|
64
|
-
import { isPinned, Title, togglePinned, Widget } from './widgets';
|
|
64
|
+
import { codicon, isPinned, Title, togglePinned, Widget } from './widgets';
|
|
65
65
|
import { SaveableService } from './saveable-service';
|
|
66
66
|
import { UserWorkingDirectoryProvider } from './user-working-directory-provider';
|
|
67
67
|
import { UNTITLED_SCHEME, UntitledResourceResolver } from '../common';
|
|
68
68
|
import { LanguageQuickPickService } from './i18n/language-quick-pick-service';
|
|
69
|
+
import { SidebarMenu } from './shell/sidebar-menu-widget';
|
|
69
70
|
|
|
70
71
|
export namespace CommonMenus {
|
|
71
72
|
|
|
@@ -472,17 +473,18 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
472
473
|
|
|
473
474
|
app.shell.leftPanelHandler.addBottomMenu({
|
|
474
475
|
id: 'settings-menu',
|
|
475
|
-
iconClass: '
|
|
476
|
+
iconClass: codicon('settings-gear'),
|
|
476
477
|
title: nls.localizeByDefault(CommonCommands.MANAGE_CATEGORY),
|
|
477
478
|
menuPath: MANAGE_MENU,
|
|
478
|
-
order:
|
|
479
|
+
order: 0,
|
|
479
480
|
});
|
|
480
|
-
const accountsMenu = {
|
|
481
|
+
const accountsMenu: SidebarMenu = {
|
|
481
482
|
id: 'accounts-menu',
|
|
482
|
-
iconClass:
|
|
483
|
+
iconClass: codicon('account'),
|
|
483
484
|
title: nls.localizeByDefault('Accounts'),
|
|
484
485
|
menuPath: ACCOUNTS_MENU,
|
|
485
|
-
order:
|
|
486
|
+
order: 1,
|
|
487
|
+
onDidBadgeChange: this.authenticationService.onDidUpdateSignInCount
|
|
486
488
|
};
|
|
487
489
|
this.authenticationService.onDidRegisterAuthenticationProvider(() => {
|
|
488
490
|
app.shell.leftPanelHandler.addBottomMenu(accountsMenu);
|
|
@@ -530,7 +532,7 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
|
|
|
530
532
|
if (newValue === 'compact') {
|
|
531
533
|
this.shell.leftPanelHandler.addTopMenu({
|
|
532
534
|
id: mainMenuId,
|
|
533
|
-
iconClass:
|
|
535
|
+
iconClass: `theia-compact-menu ${codicon('menu')}`,
|
|
534
536
|
title: nls.localizeByDefault('Application Menu'),
|
|
535
537
|
menuPath: MAIN_MENU_BAR,
|
|
536
538
|
order: 0,
|
|
@@ -35,7 +35,8 @@ import {
|
|
|
35
35
|
MenuCommandAdapterRegistry,
|
|
36
36
|
MenuCommandExecutor,
|
|
37
37
|
MenuCommandAdapterRegistryImpl,
|
|
38
|
-
MenuCommandExecutorImpl
|
|
38
|
+
MenuCommandExecutorImpl,
|
|
39
|
+
MenuPath
|
|
39
40
|
} from '../common';
|
|
40
41
|
import { KeybindingRegistry, KeybindingContext, KeybindingContribution } from './keybinding';
|
|
41
42
|
import { FrontendApplication } from './frontend-application';
|
|
@@ -137,7 +138,7 @@ import { MarkdownRenderer, MarkdownRendererFactory, MarkdownRendererImpl } from
|
|
|
137
138
|
import { StylingParticipant, StylingService } from './styling-service';
|
|
138
139
|
import { bindCommonStylingParticipants } from './common-styling-participants';
|
|
139
140
|
import { HoverService } from './hover-service';
|
|
140
|
-
import { AdditionalViewsMenuWidget, AdditionalViewsMenuWidgetFactory } from './shell/additional-views-menu-widget';
|
|
141
|
+
import { AdditionalViewsMenuPath, AdditionalViewsMenuWidget, AdditionalViewsMenuWidgetFactory } from './shell/additional-views-menu-widget';
|
|
141
142
|
import { LanguageIconLabelProvider } from './language-icon-provider';
|
|
142
143
|
import { bindTreePreferences } from './tree';
|
|
143
144
|
import { OpenWithService } from './open-with-service';
|
|
@@ -177,9 +178,9 @@ export const frontendApplicationModule = new ContainerModule((bind, _unbind, _is
|
|
|
177
178
|
bind(SidebarBottomMenuWidgetFactory).toAutoFactory(SidebarBottomMenuWidget);
|
|
178
179
|
bind(AdditionalViewsMenuWidget).toSelf();
|
|
179
180
|
bind(AdditionalViewsMenuWidgetFactory).toFactory(ctx => (side: 'left' | 'right') => {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
return
|
|
181
|
+
const childContainer = ctx.container.createChild();
|
|
182
|
+
childContainer.bind<MenuPath>(AdditionalViewsMenuPath).toConstantValue(['additional_views_menu', side]);
|
|
183
|
+
return childContainer.resolve(AdditionalViewsMenuWidget);
|
|
183
184
|
});
|
|
184
185
|
bind(SplitPositionHandler).toSelf().inSingletonScope();
|
|
185
186
|
|
|
@@ -27,6 +27,8 @@ export interface HttpOpenHandlerOptions {
|
|
|
27
27
|
@injectable()
|
|
28
28
|
export class HttpOpenHandler implements OpenHandler {
|
|
29
29
|
|
|
30
|
+
static readonly PRIORITY: number = 500;
|
|
31
|
+
|
|
30
32
|
readonly id = 'http';
|
|
31
33
|
|
|
32
34
|
@inject(WindowService)
|
|
@@ -36,7 +38,7 @@ export class HttpOpenHandler implements OpenHandler {
|
|
|
36
38
|
protected readonly externalUriService: ExternalUriService;
|
|
37
39
|
|
|
38
40
|
canHandle(uri: URI, options?: HttpOpenHandlerOptions): number {
|
|
39
|
-
return ((options && options.openExternal) || uri.scheme.startsWith('http') || uri.scheme.startsWith('mailto')) ?
|
|
41
|
+
return ((options && options.openExternal) || uri.scheme.startsWith('http') || uri.scheme.startsWith('mailto')) ? HttpOpenHandler.PRIORITY : 0;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
async open(uri: URI): Promise<undefined> {
|
|
@@ -71,25 +71,30 @@ export class BrowserMainMenuFactory implements MenuWidgetFactory {
|
|
|
71
71
|
const menuBar = new DynamicMenuBarWidget();
|
|
72
72
|
menuBar.id = 'theia:menubar';
|
|
73
73
|
this.corePreferences.ready.then(() => {
|
|
74
|
-
this.showMenuBar(menuBar
|
|
75
|
-
});
|
|
76
|
-
const preferenceListener = this.corePreferences.onPreferenceChanged(preference => {
|
|
77
|
-
if (preference.preferenceName === 'window.menuBarVisibility') {
|
|
78
|
-
this.showMenuBar(menuBar, preference.newValue);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
const keybindingListener = this.keybindingRegistry.onKeybindingsChanged(() => {
|
|
82
|
-
const preference = this.corePreferences['window.menuBarVisibility'];
|
|
83
|
-
this.showMenuBar(menuBar, preference);
|
|
84
|
-
});
|
|
85
|
-
menuBar.disposed.connect(() => {
|
|
86
|
-
preferenceListener.dispose();
|
|
87
|
-
keybindingListener.dispose();
|
|
74
|
+
this.showMenuBar(menuBar);
|
|
88
75
|
});
|
|
76
|
+
const disposable = new DisposableCollection(
|
|
77
|
+
this.corePreferences.onPreferenceChanged(change => {
|
|
78
|
+
if (change.preferenceName === 'window.menuBarVisibility') {
|
|
79
|
+
this.showMenuBar(menuBar, change.newValue);
|
|
80
|
+
}
|
|
81
|
+
}),
|
|
82
|
+
this.keybindingRegistry.onKeybindingsChanged(() => {
|
|
83
|
+
this.showMenuBar(menuBar);
|
|
84
|
+
}),
|
|
85
|
+
this.menuProvider.onDidChange(() => {
|
|
86
|
+
this.showMenuBar(menuBar);
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
menuBar.disposed.connect(() => disposable.dispose());
|
|
89
90
|
return menuBar;
|
|
90
91
|
}
|
|
91
92
|
|
|
92
|
-
protected
|
|
93
|
+
protected getMenuBarVisibility(): string {
|
|
94
|
+
return this.corePreferences.get('window.menuBarVisibility', 'classic');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
protected showMenuBar(menuBar: DynamicMenuBarWidget, preference = this.getMenuBarVisibility()): void {
|
|
93
98
|
if (preference && ['classic', 'visible'].includes(preference)) {
|
|
94
99
|
menuBar.clearMenus();
|
|
95
100
|
this.fillMenuBar(menuBar);
|
|
@@ -187,13 +192,13 @@ export class DynamicMenuBarWidget extends MenuBarWidget {
|
|
|
187
192
|
this.openActiveMenu();
|
|
188
193
|
await waitForRevealed(menu);
|
|
189
194
|
|
|
190
|
-
const menuPath = [label];
|
|
195
|
+
const menuPath = [label, ...labels];
|
|
191
196
|
|
|
192
197
|
let current = menu;
|
|
193
198
|
for (const itemLabel of labels) {
|
|
194
199
|
const item = current.items.find(i => i.label === itemLabel);
|
|
195
200
|
if (!item || !item.submenu) {
|
|
196
|
-
throw new Error(`could not find '${
|
|
201
|
+
throw new Error(`could not find '${itemLabel}' submenu in ${menuPath.map(l => "'" + l + "'").join(' -> ')} menu`);
|
|
197
202
|
}
|
|
198
203
|
current.activeItem = item;
|
|
199
204
|
current.triggerActiveItem();
|
|
@@ -211,7 +216,7 @@ export class DynamicMenuBarWidget extends MenuBarWidget {
|
|
|
211
216
|
const menu = await this.activateMenu(menuPath[0], ...menuPath.slice(1));
|
|
212
217
|
const item = menu.items.find(i => i.label === labels[labels.length - 1]);
|
|
213
218
|
if (!item) {
|
|
214
|
-
throw new Error(`could not find '${
|
|
219
|
+
throw new Error(`could not find '${labels[labels.length - 1]}' item in ${menuPath.map(l => "'" + l + "'").join(' -> ')} menu`);
|
|
215
220
|
}
|
|
216
221
|
menu.activeItem = item;
|
|
217
222
|
menu.triggerActiveItem();
|
|
@@ -468,9 +473,11 @@ export class MenuCommandRegistry extends PhosphorCommandRegistry {
|
|
|
468
473
|
});
|
|
469
474
|
|
|
470
475
|
const bindings = keybindingRegistry.getKeybindingsForCommand(id);
|
|
471
|
-
// Only consider the first keybinding.
|
|
476
|
+
// Only consider the first active keybinding.
|
|
472
477
|
if (bindings.length) {
|
|
473
|
-
const binding = bindings
|
|
478
|
+
const binding = bindings.length > 1 ?
|
|
479
|
+
bindings.find(b => !b.when || this.services.contextKeyService.match(b.when)) ?? bindings[0] :
|
|
480
|
+
bindings[0];
|
|
474
481
|
const keys = keybindingRegistry.acceleratorFor(binding, ' ', true);
|
|
475
482
|
this.addKeyBinding({
|
|
476
483
|
command: id,
|
|
@@ -20,7 +20,13 @@ import { ChannelMultiplexer } from '../../common/message-rpc/channel';
|
|
|
20
20
|
import { Deferred } from '../../common/promise-util';
|
|
21
21
|
import { ConnectionSource } from './connection-source';
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Service id for the local connection provider
|
|
25
|
+
*/
|
|
23
26
|
export const LocalConnectionProvider = Symbol('LocalConnectionProvider');
|
|
27
|
+
/**
|
|
28
|
+
* Service id for the remote connection provider
|
|
29
|
+
*/
|
|
24
30
|
export const RemoteConnectionProvider = Symbol('RemoteConnectionProvider');
|
|
25
31
|
|
|
26
32
|
export namespace ServiceConnectionProvider {
|
|
@@ -28,7 +34,15 @@ export namespace ServiceConnectionProvider {
|
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
/**
|
|
31
|
-
* This class manages the channels for remote services in the back end
|
|
37
|
+
* This class manages the channels for remote services in the back end.
|
|
38
|
+
*
|
|
39
|
+
* Since we have the ability to use a remote back end via SSH, we need to distinguish
|
|
40
|
+
* between two types of services: those that will be redirected to the remote back end
|
|
41
|
+
* and those which must remain in the local back end. For example the service that manages
|
|
42
|
+
* the remote ssh connections and port forwarding to the remote instance must remain local
|
|
43
|
+
* while e.g. the file system service will run in the remote back end. For each set
|
|
44
|
+
* of services, we will bind an instance of this class to {@linkcode LocalConnectionProvider}
|
|
45
|
+
* and {@linkcode RemoteConnectionProvider} respectively.
|
|
32
46
|
*/
|
|
33
47
|
@injectable()
|
|
34
48
|
export class ServiceConnectionProvider {
|
package/src/browser/saveable.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { Key } from './keyboard/keys';
|
|
|
22
22
|
import { AbstractDialog } from './dialogs';
|
|
23
23
|
import { nls } from '../common/nls';
|
|
24
24
|
import { DisposableCollection, isObject } from '../common';
|
|
25
|
+
import { BinaryBuffer } from '../common/buffer';
|
|
25
26
|
|
|
26
27
|
export type AutoSaveMode = 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange';
|
|
27
28
|
|
|
@@ -46,13 +47,17 @@ export interface Saveable {
|
|
|
46
47
|
*/
|
|
47
48
|
revert?(options?: Saveable.RevertOptions): Promise<void>;
|
|
48
49
|
/**
|
|
49
|
-
* Creates a snapshot of the dirty state.
|
|
50
|
+
* Creates a snapshot of the dirty state. See also {@link Saveable.Snapshot}.
|
|
50
51
|
*/
|
|
51
52
|
createSnapshot?(): Saveable.Snapshot;
|
|
52
53
|
/**
|
|
53
54
|
* Applies the given snapshot to the dirty state.
|
|
54
55
|
*/
|
|
55
56
|
applySnapshot?(snapshot: object): void;
|
|
57
|
+
/**
|
|
58
|
+
* Serializes the full state of the saveable item to a binary buffer.
|
|
59
|
+
*/
|
|
60
|
+
serialize?(): Promise<BinaryBuffer>;
|
|
56
61
|
}
|
|
57
62
|
|
|
58
63
|
export interface SaveableSource {
|
|
@@ -79,6 +84,7 @@ export class DelegatingSaveable implements Saveable {
|
|
|
79
84
|
revert?(options?: Saveable.RevertOptions): Promise<void>;
|
|
80
85
|
createSnapshot?(): Saveable.Snapshot;
|
|
81
86
|
applySnapshot?(snapshot: object): void;
|
|
87
|
+
serialize?(): Promise<BinaryBuffer>;
|
|
82
88
|
|
|
83
89
|
protected _delegate?: Saveable;
|
|
84
90
|
protected toDispose = new DisposableCollection();
|
|
@@ -101,6 +107,7 @@ export class DelegatingSaveable implements Saveable {
|
|
|
101
107
|
this.revert = delegate.revert?.bind(delegate);
|
|
102
108
|
this.createSnapshot = delegate.createSnapshot?.bind(delegate);
|
|
103
109
|
this.applySnapshot = delegate.applySnapshot?.bind(delegate);
|
|
110
|
+
this.serialize = delegate.serialize?.bind(delegate);
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
}
|
|
@@ -114,7 +121,16 @@ export namespace Saveable {
|
|
|
114
121
|
soft?: boolean
|
|
115
122
|
}
|
|
116
123
|
|
|
124
|
+
/**
|
|
125
|
+
* A snapshot of a saveable item.
|
|
126
|
+
* Applying a snapshot of a saveable on another (of the same type) using the `applySnapshot` should yield the state of the original saveable.
|
|
127
|
+
*/
|
|
117
128
|
export type Snapshot = { value: string } | { read(): string | null };
|
|
129
|
+
export namespace Snapshot {
|
|
130
|
+
export function read(snapshot: Snapshot): string | undefined {
|
|
131
|
+
return 'value' in snapshot ? snapshot.value : (snapshot.read() ?? undefined);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
118
134
|
export function isSource(arg: unknown): arg is SaveableSource {
|
|
119
135
|
return isObject<SaveableSource>(arg) && is(arg.saveable);
|
|
120
136
|
}
|
|
@@ -23,13 +23,13 @@ import { SideTabBar } from './tab-bars';
|
|
|
23
23
|
export const AdditionalViewsMenuWidgetFactory = Symbol('AdditionalViewsMenuWidgetFactory');
|
|
24
24
|
export type AdditionalViewsMenuWidgetFactory = (side: 'left' | 'right') => AdditionalViewsMenuWidget;
|
|
25
25
|
|
|
26
|
-
export const
|
|
27
|
-
|
|
26
|
+
export const AdditionalViewsMenuPath = Symbol('AdditionalViewsMenuPath');
|
|
28
27
|
@injectable()
|
|
29
28
|
export class AdditionalViewsMenuWidget extends SidebarMenuWidget {
|
|
30
29
|
static readonly ID = 'sidebar.additional.views';
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
@inject(AdditionalViewsMenuPath)
|
|
32
|
+
protected menuPath: MenuPath;
|
|
33
33
|
|
|
34
34
|
@inject(CommandRegistry)
|
|
35
35
|
protected readonly commandRegistry: CommandRegistry;
|
|
@@ -47,7 +47,7 @@ export class AdditionalViewsMenuWidget extends SidebarMenuWidget {
|
|
|
47
47
|
title: nls.localizeByDefault('Additional Views'),
|
|
48
48
|
iconClass: codicon('ellipsis'),
|
|
49
49
|
id: AdditionalViewsMenuWidget.ID,
|
|
50
|
-
menuPath:
|
|
50
|
+
menuPath: this.menuPath,
|
|
51
51
|
order: 0
|
|
52
52
|
});
|
|
53
53
|
}
|
|
@@ -66,6 +66,6 @@ export class AdditionalViewsMenuWidget extends SidebarMenuWidget {
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
}));
|
|
69
|
-
this.menuDisposables.push(this.menuModelRegistry.registerMenuAction(
|
|
69
|
+
this.menuDisposables.push(this.menuModelRegistry.registerMenuAction(this.menuPath, { commandId: command.id, order: index.toString() }));
|
|
70
70
|
}
|
|
71
71
|
}
|
|
@@ -960,7 +960,7 @@ export class ApplicationShell extends Widget {
|
|
|
960
960
|
}
|
|
961
961
|
}
|
|
962
962
|
|
|
963
|
-
getInsertionOptions(options?: Readonly<ApplicationShell.WidgetOptions>): { area: string; addOptions:
|
|
963
|
+
getInsertionOptions(options?: Readonly<ApplicationShell.WidgetOptions>): { area: string; addOptions: TheiaDockPanel.AddOptions; } {
|
|
964
964
|
let ref: Widget | undefined = options?.ref;
|
|
965
965
|
let area: ApplicationShell.Area = options?.area || 'main';
|
|
966
966
|
if (!ref && (area === 'main' || area === 'bottom')) {
|
|
@@ -969,7 +969,7 @@ export class ApplicationShell extends Widget {
|
|
|
969
969
|
}
|
|
970
970
|
// make sure that ref belongs to area
|
|
971
971
|
area = ref && this.getAreaFor(ref) || area;
|
|
972
|
-
const addOptions:
|
|
972
|
+
const addOptions: TheiaDockPanel.AddOptions = {};
|
|
973
973
|
if (ApplicationShell.isOpenToSideMode(options?.mode)) {
|
|
974
974
|
const areaPanel = area === 'main' ? this.mainPanel : area === 'bottom' ? this.bottomPanel : undefined;
|
|
975
975
|
const sideRef = areaPanel && ref && (options?.mode === 'open-to-left' ?
|
|
@@ -981,6 +981,10 @@ export class ApplicationShell extends Widget {
|
|
|
981
981
|
addOptions.ref = ref;
|
|
982
982
|
addOptions.mode = options?.mode === 'open-to-left' ? 'split-left' : 'split-right';
|
|
983
983
|
}
|
|
984
|
+
} else if (ApplicationShell.isReplaceMode(options?.mode)) {
|
|
985
|
+
addOptions.ref = options?.ref;
|
|
986
|
+
addOptions.closeRef = true;
|
|
987
|
+
addOptions.mode = 'tab-after';
|
|
984
988
|
} else {
|
|
985
989
|
addOptions.ref = ref;
|
|
986
990
|
addOptions.mode = options?.mode;
|
|
@@ -1892,6 +1896,10 @@ export class ApplicationShell extends Widget {
|
|
|
1892
1896
|
if (index < current.titles.length - 1) {
|
|
1893
1897
|
return index + 1;
|
|
1894
1898
|
}
|
|
1899
|
+
// last item in tab bar. select the previous one.
|
|
1900
|
+
if (index === current.titles.length - 1) {
|
|
1901
|
+
return index - 1;
|
|
1902
|
+
}
|
|
1895
1903
|
return 0;
|
|
1896
1904
|
}
|
|
1897
1905
|
|
|
@@ -2058,7 +2066,7 @@ export class ApplicationShell extends Widget {
|
|
|
2058
2066
|
*/
|
|
2059
2067
|
async saveAll(options?: SaveOptions): Promise<void> {
|
|
2060
2068
|
for (const widget of this.widgets) {
|
|
2061
|
-
if (this.saveableService.canSaveNotSaveAs(widget)) {
|
|
2069
|
+
if (Saveable.isDirty(widget) && this.saveableService.canSaveNotSaveAs(widget)) {
|
|
2062
2070
|
await this.saveableService.save(widget, options);
|
|
2063
2071
|
}
|
|
2064
2072
|
}
|
|
@@ -2172,6 +2180,15 @@ export namespace ApplicationShell {
|
|
|
2172
2180
|
return mode === 'open-to-left' || mode === 'open-to-right';
|
|
2173
2181
|
}
|
|
2174
2182
|
|
|
2183
|
+
/**
|
|
2184
|
+
* Whether the `ref` of the options widget should be replaced.
|
|
2185
|
+
*/
|
|
2186
|
+
export type ReplaceMode = 'tab-replace';
|
|
2187
|
+
|
|
2188
|
+
export function isReplaceMode(mode: unknown): mode is ReplaceMode {
|
|
2189
|
+
return mode === 'tab-replace';
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2175
2192
|
/**
|
|
2176
2193
|
* Options for adding a widget to the application shell.
|
|
2177
2194
|
*/
|
|
@@ -2185,7 +2202,7 @@ export namespace ApplicationShell {
|
|
|
2185
2202
|
*
|
|
2186
2203
|
* The default is `'tab-after'`.
|
|
2187
2204
|
*/
|
|
2188
|
-
mode?: DockLayout.InsertMode | OpenToSideMode
|
|
2205
|
+
mode?: DockLayout.InsertMode | OpenToSideMode | ReplaceMode
|
|
2189
2206
|
/**
|
|
2190
2207
|
* The reference widget for the insert location.
|
|
2191
2208
|
*
|
|
@@ -211,6 +211,7 @@ export class SidePanelHandler {
|
|
|
211
211
|
protected createAdditionalViewsWidget(): AdditionalViewsMenuWidget {
|
|
212
212
|
const widget = this.additionalViewsMenuFactory(this.side);
|
|
213
213
|
widget.addClass('theia-sidebar-menu');
|
|
214
|
+
widget.addClass('theia-additional-views-menu');
|
|
214
215
|
return widget;
|
|
215
216
|
}
|
|
216
217
|
|
|
@@ -653,7 +654,7 @@ export class SidePanelHandler {
|
|
|
653
654
|
}
|
|
654
655
|
|
|
655
656
|
protected onTabsOverflowChanged(sender: SideTabBar, event: { titles: Title<Widget>[], startIndex: number }): void {
|
|
656
|
-
if (event.startIndex
|
|
657
|
+
if (event.startIndex > 0 && event.startIndex <= sender.currentIndex) {
|
|
657
658
|
sender.revealTab(sender.currentIndex);
|
|
658
659
|
} else {
|
|
659
660
|
this.additionalViewsMenu.updateAdditionalViews(sender, event);
|
|
@@ -20,6 +20,7 @@ import { ReactWidget } from '../widgets';
|
|
|
20
20
|
import { ContextMenuRenderer } from '../context-menu-renderer';
|
|
21
21
|
import { MenuPath } from '../../common/menu';
|
|
22
22
|
import { HoverService } from '../hover-service';
|
|
23
|
+
import { Event, Disposable, Emitter, DisposableCollection } from '../../common';
|
|
23
24
|
|
|
24
25
|
export const SidebarTopMenuWidgetFactory = Symbol('SidebarTopMenuWidgetFactory');
|
|
25
26
|
export const SidebarBottomMenuWidgetFactory = Symbol('SidebarBottomMenuWidgetFactory');
|
|
@@ -29,18 +30,54 @@ export interface SidebarMenu {
|
|
|
29
30
|
iconClass: string;
|
|
30
31
|
title: string;
|
|
31
32
|
menuPath: MenuPath;
|
|
33
|
+
onDidBadgeChange?: Event<number>;
|
|
32
34
|
/*
|
|
33
35
|
* Used to sort menus. The lower the value the lower they are placed in the sidebar.
|
|
34
36
|
*/
|
|
35
37
|
order: number;
|
|
36
38
|
}
|
|
37
39
|
|
|
40
|
+
export class SidebarMenuItem implements Disposable {
|
|
41
|
+
|
|
42
|
+
readonly menu: SidebarMenu;
|
|
43
|
+
get badge(): string {
|
|
44
|
+
if (this._badge <= 0) {
|
|
45
|
+
return '';
|
|
46
|
+
} else if (this._badge > 99) {
|
|
47
|
+
return '99+';
|
|
48
|
+
} else {
|
|
49
|
+
return this._badge.toString();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
protected readonly onDidBadgeChangeEmitter = new Emitter<number>();
|
|
53
|
+
readonly onDidBadgeChange: Event<number> = this.onDidBadgeChangeEmitter.event;
|
|
54
|
+
protected _badge = 0;
|
|
55
|
+
|
|
56
|
+
protected readonly toDispose = new DisposableCollection();
|
|
57
|
+
|
|
58
|
+
constructor(menu: SidebarMenu) {
|
|
59
|
+
this.menu = menu;
|
|
60
|
+
if (menu.onDidBadgeChange) {
|
|
61
|
+
this.toDispose.push(menu.onDidBadgeChange(value => {
|
|
62
|
+
this._badge = value;
|
|
63
|
+
this.onDidBadgeChangeEmitter.fire(value);
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
dispose(): void {
|
|
69
|
+
this.toDispose.dispose();
|
|
70
|
+
this.onDidBadgeChangeEmitter.dispose();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
38
75
|
/**
|
|
39
76
|
* The menu widget placed on the sidebar.
|
|
40
77
|
*/
|
|
41
78
|
@injectable()
|
|
42
79
|
export class SidebarMenuWidget extends ReactWidget {
|
|
43
|
-
protected readonly
|
|
80
|
+
protected readonly items: SidebarMenuItem[];
|
|
44
81
|
/**
|
|
45
82
|
* The element that had focus when a menu rendered by this widget was activated.
|
|
46
83
|
*/
|
|
@@ -58,27 +95,27 @@ export class SidebarMenuWidget extends ReactWidget {
|
|
|
58
95
|
|
|
59
96
|
constructor() {
|
|
60
97
|
super();
|
|
61
|
-
this.
|
|
98
|
+
this.items = [];
|
|
62
99
|
}
|
|
63
100
|
|
|
64
101
|
addMenu(menu: SidebarMenu): void {
|
|
65
|
-
const exists = this.
|
|
102
|
+
const exists = this.items.find(item => item.menu.id === menu.id);
|
|
66
103
|
if (exists) {
|
|
67
104
|
return;
|
|
68
105
|
}
|
|
69
|
-
|
|
70
|
-
|
|
106
|
+
const newItem = new SidebarMenuItem(menu);
|
|
107
|
+
newItem.onDidBadgeChange(() => this.update());
|
|
108
|
+
this.items.push(newItem);
|
|
109
|
+
this.items.sort((a, b) => a.menu.order - b.menu.order);
|
|
71
110
|
this.update();
|
|
72
111
|
}
|
|
73
112
|
|
|
74
113
|
removeMenu(menuId: string): void {
|
|
75
|
-
const
|
|
76
|
-
if (
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
this.update();
|
|
81
|
-
}
|
|
114
|
+
const index = this.items.findIndex(m => m.menu.id === menuId);
|
|
115
|
+
if (index !== -1) {
|
|
116
|
+
this.items[index].dispose();
|
|
117
|
+
this.items.splice(index, 1);
|
|
118
|
+
this.update();
|
|
82
119
|
}
|
|
83
120
|
}
|
|
84
121
|
|
|
@@ -127,14 +164,20 @@ export class SidebarMenuWidget extends ReactWidget {
|
|
|
127
164
|
|
|
128
165
|
protected render(): React.ReactNode {
|
|
129
166
|
return <React.Fragment>
|
|
130
|
-
{this.
|
|
131
|
-
key={menu.id}
|
|
132
|
-
className={menu.iconClass}
|
|
133
|
-
onClick={e => this.onClick(e, menu.menuPath)}
|
|
134
|
-
onMouseDown={this.onMouseDown}
|
|
135
|
-
onMouseEnter={e => this.onMouseEnter(e, menu.title)}
|
|
136
|
-
onMouseLeave={this.onMouseOut}
|
|
137
|
-
/>)}
|
|
167
|
+
{this.items.map(item => this.renderItem(item))}
|
|
138
168
|
</React.Fragment>;
|
|
139
169
|
}
|
|
170
|
+
|
|
171
|
+
protected renderItem(item: SidebarMenuItem): React.ReactNode {
|
|
172
|
+
return <div
|
|
173
|
+
key={item.menu.id}
|
|
174
|
+
className='theia-sidebar-menu-item'
|
|
175
|
+
onClick={e => this.onClick(e, item.menu.menuPath)}
|
|
176
|
+
onMouseDown={this.onMouseDown}
|
|
177
|
+
onMouseEnter={e => this.onMouseEnter(e, item.menu.title)}
|
|
178
|
+
onMouseLeave={this.onMouseOut}>
|
|
179
|
+
<i className={item.menu.iconClass} />
|
|
180
|
+
{item.badge && <div className='theia-badge-decorator-sidebar'>{item.badge}</div>}
|
|
181
|
+
</div>;
|
|
182
|
+
}
|
|
140
183
|
}
|
|
@@ -91,13 +91,14 @@ export class SplitPositionHandler {
|
|
|
91
91
|
move.resolve = resolve;
|
|
92
92
|
move.reject = reject;
|
|
93
93
|
if (this.splitMoves.length === 0) {
|
|
94
|
-
|
|
94
|
+
setTimeout(this.animationFrame.bind(this), 10);
|
|
95
95
|
}
|
|
96
96
|
this.splitMoves.push(move);
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
protected animationFrame(
|
|
100
|
+
protected animationFrame(): void {
|
|
101
|
+
const time = Date.now();
|
|
101
102
|
const move = this.splitMoves[this.currentMoveIndex];
|
|
102
103
|
let rejectedOrResolved = false;
|
|
103
104
|
if (move.ended || move.referenceWidget && move.referenceWidget.isHidden) {
|
|
@@ -133,7 +134,7 @@ export class SplitPositionHandler {
|
|
|
133
134
|
this.currentMoveIndex = 0;
|
|
134
135
|
}
|
|
135
136
|
if (this.splitMoves.length > 0) {
|
|
136
|
-
|
|
137
|
+
setTimeout(this.animationFrame.bind(this));
|
|
137
138
|
}
|
|
138
139
|
}
|
|
139
140
|
|