@theia/core 1.28.0-next.9 → 1.28.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 +6 -6
- package/i18n/nls.cs.json +33 -2
- package/i18n/nls.de.json +33 -2
- package/i18n/nls.es.json +33 -2
- package/i18n/nls.fr.json +33 -2
- package/i18n/nls.hu.json +33 -2
- package/i18n/nls.it.json +33 -2
- package/i18n/nls.ja.json +33 -2
- package/i18n/nls.json +35 -4
- package/i18n/nls.pl.json +33 -2
- package/i18n/nls.pt-br.json +33 -2
- package/i18n/nls.pt-pt.json +33 -2
- package/i18n/nls.ru.json +33 -2
- package/i18n/nls.zh-cn.json +33 -2
- package/lib/browser/common-frontend-contribution.d.ts +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/context-key-service.d.ts +3 -1
- package/lib/browser/context-key-service.d.ts.map +1 -1
- package/lib/browser/context-menu-renderer.d.ts +5 -0
- package/lib/browser/context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.d.ts.map +1 -1
- package/lib/browser/frontend-application-module.js +2 -0
- package/lib/browser/frontend-application-module.js.map +1 -1
- package/lib/browser/frontend-application.d.ts +3 -2
- package/lib/browser/frontend-application.d.ts.map +1 -1
- package/lib/browser/frontend-application.js.map +1 -1
- package/lib/browser/keybinding.d.ts.map +1 -1
- package/lib/browser/keybinding.js +9 -7
- package/lib/browser/keybinding.js.map +1 -1
- package/lib/browser/keybinding.spec.js +13 -3
- package/lib/browser/keybinding.spec.js.map +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.d.ts +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.d.ts.map +1 -1
- package/lib/browser/menu/browser-context-menu-renderer.js +2 -2
- package/lib/browser/menu/browser-context-menu-renderer.js.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.d.ts +23 -24
- package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
- package/lib/browser/menu/browser-menu-plugin.js +62 -79
- package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
- package/lib/browser/resource-context-key.d.ts +1 -0
- package/lib/browser/resource-context-key.d.ts.map +1 -1
- package/lib/browser/resource-context-key.js +8 -6
- package/lib/browser/resource-context-key.js.map +1 -1
- package/lib/browser/shell/shell-layout-restorer.d.ts.map +1 -1
- package/lib/browser/shell/shell-layout-restorer.js +2 -1
- package/lib/browser/shell/shell-layout-restorer.js.map +1 -1
- package/lib/browser/shell/side-panel-toolbar.d.ts.map +1 -1
- package/lib/browser/shell/side-panel-toolbar.js +0 -1
- package/lib/browser/shell/side-panel-toolbar.js.map +1 -1
- package/lib/browser/shell/tab-bar-toolbar/index.d.ts +4 -0
- package/lib/browser/shell/tab-bar-toolbar/index.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/index.js +31 -0
- package/lib/browser/shell/tab-bar-toolbar/index.js.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts +16 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +36 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts +51 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +173 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts +119 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js +67 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts +53 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts.map +1 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js +264 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -0
- package/lib/browser/shell/{tab-bar-toolbar.spec.d.ts → tab-bar-toolbar/tab-bar-toolbar.spec.d.ts} +0 -0
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.d.ts.map +1 -0
- package/lib/browser/shell/{tab-bar-toolbar.spec.js → tab-bar-toolbar/tab-bar-toolbar.spec.js} +3 -3
- package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js.map +1 -0
- package/lib/browser/view-container.d.ts.map +1 -1
- package/lib/browser/view-container.js +1 -10
- package/lib/browser/view-container.js.map +1 -1
- package/lib/browser/widget-manager.d.ts.map +1 -1
- package/lib/browser/widget-manager.js +2 -1
- package/lib/browser/widget-manager.js.map +1 -1
- package/lib/browser/widget-manager.spec.js +13 -0
- package/lib/browser/widget-manager.spec.js.map +1 -1
- package/lib/browser/window/default-window-service.d.ts +2 -1
- package/lib/browser/window/default-window-service.d.ts.map +1 -1
- package/lib/browser/window/default-window-service.js +9 -4
- package/lib/browser/window/default-window-service.js.map +1 -1
- package/lib/browser/window/window-service.d.ts +2 -1
- package/lib/browser/window/window-service.d.ts.map +1 -1
- package/lib/browser/window/window-service.js.map +1 -1
- package/lib/common/color.d.ts +3 -0
- package/lib/common/color.d.ts.map +1 -1
- package/lib/common/frontend-application-state.d.ts +14 -0
- package/lib/common/frontend-application-state.d.ts.map +1 -1
- package/lib/common/frontend-application-state.js +16 -0
- package/lib/common/frontend-application-state.js.map +1 -1
- package/lib/common/menu/action-menu-node.d.ts +20 -0
- package/lib/common/menu/action-menu-node.d.ts.map +1 -0
- package/lib/common/menu/action-menu-node.js +57 -0
- package/lib/common/menu/action-menu-node.js.map +1 -0
- package/lib/common/menu/composite-menu-node.d.ts +52 -0
- package/lib/common/menu/composite-menu-node.d.ts.map +1 -0
- package/lib/common/menu/composite-menu-node.js +102 -0
- package/lib/common/menu/composite-menu-node.js.map +1 -0
- package/lib/common/menu/index.d.ts +6 -0
- package/lib/common/menu/index.d.ts.map +1 -0
- package/lib/common/menu/index.js +33 -0
- package/lib/common/menu/index.js.map +1 -0
- package/lib/common/menu/menu-adapter.d.ts +36 -0
- package/lib/common/menu/menu-adapter.d.ts.map +1 -0
- package/lib/common/menu/menu-adapter.js +101 -0
- package/lib/common/menu/menu-adapter.js.map +1 -0
- package/lib/common/{menu.d.ts → menu/menu-model-registry.d.ts} +22 -124
- package/lib/common/menu/menu-model-registry.d.ts.map +1 -0
- package/lib/common/{menu.js → menu/menu-model-registry.js} +71 -147
- package/lib/common/menu/menu-model-registry.js.map +1 -0
- package/lib/common/menu/menu-types.d.ts +120 -0
- package/lib/common/menu/menu-types.d.ts.map +1 -0
- package/lib/common/menu/menu-types.js +84 -0
- package/lib/common/menu/menu-types.js.map +1 -0
- package/lib/common/{menu.spec.d.ts → menu/menu.spec.d.ts} +0 -0
- package/lib/common/menu/menu.spec.d.ts.map +1 -0
- package/lib/common/{menu.spec.js → menu/menu.spec.js} +3 -3
- package/lib/common/menu/menu.spec.js.map +1 -0
- package/lib/common/messaging/abstract-connection-provider.d.ts +1 -1
- package/lib/common/messaging/abstract-connection-provider.js +3 -3
- package/lib/common/quick-pick-service.d.ts +1 -0
- 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-context-menu-renderer.js +2 -2
- package/lib/electron-browser/menu/electron-context-menu-renderer.js.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +14 -5
- package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-main-menu-factory.js +71 -82
- package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
- package/lib/electron-browser/menu/electron-menu-contribution.js +6 -0
- package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
- package/lib/electron-browser/messaging/electron-ws-connection-provider.js +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-common/messaging/electron-messages.d.ts +3 -14
- package/lib/electron-common/messaging/electron-messages.d.ts.map +1 -1
- package/lib/electron-common/messaging/electron-messages.js +3 -16
- package/lib/electron-common/messaging/electron-messages.js.map +1 -1
- package/lib/electron-main/messaging/electron-messaging-contribution.d.ts +3 -3
- package/lib/electron-main/messaging/electron-messaging-contribution.js +6 -6
- package/package.json +7 -6
- package/src/browser/common-frontend-contribution.ts +6 -5
- package/src/browser/context-key-service.ts +1 -1
- package/src/browser/context-menu-renderer.ts +5 -0
- package/src/browser/frontend-application-module.ts +7 -1
- package/src/browser/frontend-application.ts +3 -2
- package/src/browser/keybinding.spec.ts +13 -3
- package/src/browser/keybinding.ts +8 -9
- package/src/browser/menu/browser-context-menu-renderer.ts +2 -2
- package/src/browser/menu/browser-menu-plugin.ts +74 -86
- package/src/browser/resource-context-key.ts +9 -6
- package/src/browser/shell/shell-layout-restorer.ts +2 -1
- package/src/browser/shell/side-panel-toolbar.ts +0 -1
- package/src/browser/shell/tab-bar-toolbar/index.ts +19 -0
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.ts +31 -0
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +170 -0
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.ts +186 -0
- package/src/browser/shell/{tab-bar-toolbar.spec.ts → tab-bar-toolbar/tab-bar-toolbar.spec.ts} +2 -2
- package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +261 -0
- package/src/browser/style/alert-messages.css +6 -0
- package/src/browser/view-container.ts +1 -10
- package/src/browser/widget-manager.spec.ts +14 -0
- package/src/browser/widget-manager.ts +2 -1
- package/src/browser/window/default-window-service.ts +9 -4
- package/src/browser/window/window-service.ts +2 -1
- package/src/common/color.ts +3 -0
- package/src/common/frontend-application-state.ts +15 -0
- package/src/common/menu/action-menu-node.ts +65 -0
- package/src/common/menu/composite-menu-node.ts +121 -0
- package/src/common/menu/index.ts +21 -0
- package/src/common/menu/menu-adapter.ts +103 -0
- package/src/common/{menu.ts → menu/menu-model-registry.ts} +61 -222
- package/src/common/menu/menu-types.ts +183 -0
- package/src/common/{menu.spec.ts → menu/menu.spec.ts} +3 -2
- package/src/common/messaging/abstract-connection-provider.ts +4 -4
- package/src/common/quick-pick-service.ts +1 -0
- package/src/electron-browser/menu/electron-context-menu-renderer.ts +2 -2
- package/src/electron-browser/menu/electron-main-menu-factory.ts +82 -96
- package/src/electron-browser/menu/electron-menu-contribution.ts +8 -0
- package/src/electron-browser/messaging/electron-ws-connection-provider.ts +1 -1
- package/src/electron-browser/window/electron-window-service.ts +1 -1
- package/src/electron-common/messaging/electron-messages.ts +4 -15
- package/src/electron-main/messaging/electron-messaging-contribution.ts +8 -8
- package/lib/browser/shell/tab-bar-toolbar.d.ts +0 -186
- package/lib/browser/shell/tab-bar-toolbar.d.ts.map +0 -1
- package/lib/browser/shell/tab-bar-toolbar.js +0 -362
- package/lib/browser/shell/tab-bar-toolbar.js.map +0 -1
- package/lib/browser/shell/tab-bar-toolbar.spec.d.ts.map +0 -1
- package/lib/browser/shell/tab-bar-toolbar.spec.js.map +0 -1
- package/lib/common/menu.d.ts.map +0 -1
- package/lib/common/menu.js.map +0 -1
- package/lib/common/menu.spec.d.ts.map +0 -1
- package/lib/common/menu.spec.js.map +0 -1
- package/src/browser/shell/tab-bar-toolbar.tsx +0 -495
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import { inject, named, injectable } from 'inversify';
|
|
18
18
|
import { Widget } from '@phosphor/widgets';
|
|
19
19
|
import { ILogger, Emitter, Event, ContributionProvider, MaybePromise, WaitUntilEvent } from '../common';
|
|
20
|
+
import stableJsonStringify = require('fast-json-stable-stringify');
|
|
20
21
|
|
|
21
22
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
22
23
|
export const WidgetFactory = Symbol('WidgetFactory');
|
|
@@ -256,7 +257,7 @@ export class WidgetManager {
|
|
|
256
257
|
* @returns the widget construction options represented as a string.
|
|
257
258
|
*/
|
|
258
259
|
protected toKey(options: WidgetConstructionOptions): string {
|
|
259
|
-
return
|
|
260
|
+
return stableJsonStringify(options);
|
|
260
261
|
}
|
|
261
262
|
|
|
262
263
|
/**
|
|
@@ -22,6 +22,7 @@ import { FrontendApplicationContribution, FrontendApplication, OnWillStopAction
|
|
|
22
22
|
import { WindowService } from './window-service';
|
|
23
23
|
import { DEFAULT_WINDOW_HASH } from '../../common/window';
|
|
24
24
|
import { confirmExit } from '../dialogs';
|
|
25
|
+
import { StopReason } from '../../common/frontend-application-state';
|
|
25
26
|
|
|
26
27
|
@injectable()
|
|
27
28
|
export class DefaultWindowService implements WindowService, FrontendApplicationContribution {
|
|
@@ -97,16 +98,16 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
97
98
|
window.addEventListener('unload', () => this.onUnloadEmitter.fire());
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
async isSafeToShutDown(): Promise<boolean> {
|
|
101
|
+
async isSafeToShutDown(stopReason: StopReason): Promise<boolean> {
|
|
101
102
|
const vetoes = this.collectContributionUnloadVetoes();
|
|
102
103
|
if (vetoes.length === 0) {
|
|
103
104
|
return true;
|
|
104
105
|
}
|
|
105
|
-
const preparedValues = await Promise.all(vetoes.map(e => e.prepare?.()));
|
|
106
|
+
const preparedValues = await Promise.all(vetoes.map(e => e.prepare?.(stopReason)));
|
|
106
107
|
console.debug('Shutdown prevented by', vetoes.map(({ reason }) => reason).join(', '));
|
|
107
108
|
for (let i = 0; i < vetoes.length; i++) {
|
|
108
109
|
try {
|
|
109
|
-
const result = await vetoes[i].action(preparedValues[i]);
|
|
110
|
+
const result = await vetoes[i].action(preparedValues[i], stopReason);
|
|
110
111
|
if (!result) {
|
|
111
112
|
return false;
|
|
112
113
|
}
|
|
@@ -156,6 +157,10 @@ export class DefaultWindowService implements WindowService, FrontendApplicationC
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
reload(): void {
|
|
159
|
-
|
|
160
|
+
this.isSafeToShutDown(StopReason.Reload).then(isSafe => {
|
|
161
|
+
if (isSafe) {
|
|
162
|
+
window.location.reload();
|
|
163
|
+
}
|
|
164
|
+
});
|
|
160
165
|
}
|
|
161
166
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
+
import { StopReason } from '../../common/frontend-application-state';
|
|
17
18
|
import { Event } from '../../common/event';
|
|
18
19
|
import { NewWindowOptions } from '../../common/window';
|
|
19
20
|
|
|
@@ -49,7 +50,7 @@ export interface WindowService {
|
|
|
49
50
|
* will not be called again in the current session. I.e. if this return `true`, the shutdown should proceed without
|
|
50
51
|
* further condition.
|
|
51
52
|
*/
|
|
52
|
-
isSafeToShutDown(): Promise<boolean>;
|
|
53
|
+
isSafeToShutDown(reason: StopReason): Promise<boolean>;
|
|
53
54
|
|
|
54
55
|
/**
|
|
55
56
|
* Will prevent subsequent checks of `FrontendApplicationContribution#willStop`. Should only be used after requesting
|
package/src/common/color.ts
CHANGED
|
@@ -85,7 +85,10 @@ export interface HSLA {
|
|
|
85
85
|
export interface ColorDefaults {
|
|
86
86
|
light?: Color
|
|
87
87
|
dark?: Color
|
|
88
|
+
/** @deprecated @since 1.28.0 Please use hcDark and hcLight. This field will be ignored unless `hcDark` is absent. */
|
|
88
89
|
hc?: Color
|
|
90
|
+
hcDark?: Color;
|
|
91
|
+
hcLight?: Color;
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
export interface ColorDefinition {
|
|
@@ -21,3 +21,18 @@ export type FrontendApplicationState =
|
|
|
21
21
|
| 'initialized_layout'
|
|
22
22
|
| 'ready'
|
|
23
23
|
| 'closing_window';
|
|
24
|
+
|
|
25
|
+
export enum StopReason {
|
|
26
|
+
/**
|
|
27
|
+
* Closing the window with no prospect of restart.
|
|
28
|
+
*/
|
|
29
|
+
Close,
|
|
30
|
+
/**
|
|
31
|
+
* Reload without closing the window.
|
|
32
|
+
*/
|
|
33
|
+
Reload,
|
|
34
|
+
/**
|
|
35
|
+
* Reload that includes closing the window.
|
|
36
|
+
*/
|
|
37
|
+
Restart,
|
|
38
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { CommandRegistry } from '../command';
|
|
18
|
+
import { AlternativeHandlerMenuNode, CommandMenuNode, MenuAction, MenuNode } from './menu-types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Node representing an action in the menu tree structure.
|
|
22
|
+
* It's based on {@link MenuAction} for which it tries to determine the
|
|
23
|
+
* best label, icon and sortString with the given data.
|
|
24
|
+
*/
|
|
25
|
+
export class ActionMenuNode implements MenuNode, CommandMenuNode, Partial<AlternativeHandlerMenuNode> {
|
|
26
|
+
|
|
27
|
+
readonly altNode: ActionMenuNode | undefined;
|
|
28
|
+
|
|
29
|
+
constructor(
|
|
30
|
+
protected readonly action: MenuAction,
|
|
31
|
+
protected readonly commands: CommandRegistry,
|
|
32
|
+
) {
|
|
33
|
+
if (action.alt) {
|
|
34
|
+
this.altNode = new ActionMenuNode({ commandId: action.alt }, commands);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get command(): string { return this.action.commandId; };
|
|
39
|
+
|
|
40
|
+
get when(): string | undefined { return this.action.when; }
|
|
41
|
+
|
|
42
|
+
get id(): string { return this.action.commandId; }
|
|
43
|
+
|
|
44
|
+
get label(): string {
|
|
45
|
+
if (this.action.label) {
|
|
46
|
+
return this.action.label;
|
|
47
|
+
}
|
|
48
|
+
const cmd = this.commands.getCommand(this.action.commandId);
|
|
49
|
+
if (!cmd) {
|
|
50
|
+
console.debug(`No label for action menu node: No command "${this.action.commandId}" exists.`);
|
|
51
|
+
return '';
|
|
52
|
+
}
|
|
53
|
+
return cmd.label || cmd.id;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get icon(): string | undefined {
|
|
57
|
+
if (this.action.icon) {
|
|
58
|
+
return this.action.icon;
|
|
59
|
+
}
|
|
60
|
+
const command = this.commands.getCommand(this.action.commandId);
|
|
61
|
+
return command && command.iconClass;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get sortString(): string { return this.action.order || this.label; }
|
|
65
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { Disposable } from '../disposable';
|
|
18
|
+
import { CompoundMenuNode, CompoundMenuNodeMetadata, CompoundMenuNodeRole, MenuNode, SubMenuOptions } from './menu-types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Node representing a (sub)menu in the menu tree structure.
|
|
22
|
+
*/
|
|
23
|
+
export class CompositeMenuNode implements MenuNode, CompoundMenuNode, CompoundMenuNodeMetadata {
|
|
24
|
+
protected readonly _children: MenuNode[] = [];
|
|
25
|
+
public iconClass?: string;
|
|
26
|
+
public order?: string;
|
|
27
|
+
readonly when?: string;
|
|
28
|
+
readonly _role?: CompoundMenuNodeRole;
|
|
29
|
+
|
|
30
|
+
constructor(
|
|
31
|
+
public readonly id: string,
|
|
32
|
+
public label?: string,
|
|
33
|
+
options?: SubMenuOptions,
|
|
34
|
+
readonly parent?: MenuNode & CompoundMenuNode,
|
|
35
|
+
) {
|
|
36
|
+
if (options) {
|
|
37
|
+
this.iconClass = options.iconClass;
|
|
38
|
+
this.order = options.order;
|
|
39
|
+
this.when = options.when;
|
|
40
|
+
this._role = options?.role;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get icon(): string | undefined {
|
|
45
|
+
return this.iconClass;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get children(): ReadonlyArray<MenuNode> {
|
|
49
|
+
return this._children;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get role(): CompoundMenuNodeRole { return this._role ?? (this.label ? CompoundMenuNodeRole.Submenu : CompoundMenuNodeRole.Group); }
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Inserts the given node at the position indicated by `sortString`.
|
|
56
|
+
*
|
|
57
|
+
* @returns a disposable which, when called, will remove the given node again.
|
|
58
|
+
*/
|
|
59
|
+
public addNode(node: MenuNode): Disposable {
|
|
60
|
+
this._children.push(node);
|
|
61
|
+
this._children.sort(CompoundMenuNode.sortChildren);
|
|
62
|
+
return {
|
|
63
|
+
dispose: () => {
|
|
64
|
+
const idx = this._children.indexOf(node);
|
|
65
|
+
if (idx >= 0) {
|
|
66
|
+
this._children.splice(idx, 1);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Removes the first node with the given id.
|
|
74
|
+
*
|
|
75
|
+
* @param id node id.
|
|
76
|
+
*/
|
|
77
|
+
public removeNode(id: string): void {
|
|
78
|
+
const node = this._children.find(n => n.id === id);
|
|
79
|
+
if (node) {
|
|
80
|
+
const idx = this._children.indexOf(node);
|
|
81
|
+
if (idx >= 0) {
|
|
82
|
+
this._children.splice(idx, 1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get sortString(): string {
|
|
88
|
+
return this.order || this.id;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get isSubmenu(): boolean {
|
|
92
|
+
return Boolean(this.label);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** @deprecated @since 1.28 use CompoundMenuNode.isNavigationGroup instead */
|
|
96
|
+
static isNavigationGroup = CompoundMenuNode.isNavigationGroup;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export class CompositeMenuNodeWrapper implements MenuNode, CompoundMenuNodeMetadata {
|
|
100
|
+
constructor(protected readonly wrapped: Readonly<CompositeMenuNode>, readonly parent: MenuNode & CompoundMenuNode, protected readonly options?: SubMenuOptions) { }
|
|
101
|
+
|
|
102
|
+
get id(): string { return this.wrapped.id; }
|
|
103
|
+
|
|
104
|
+
get label(): string | undefined { return this.wrapped.label; }
|
|
105
|
+
|
|
106
|
+
get sortString(): string { return this.order || this.id; }
|
|
107
|
+
|
|
108
|
+
get isSubmenu(): boolean { return Boolean(this.label); }
|
|
109
|
+
|
|
110
|
+
get role(): CompoundMenuNodeRole { return this.options?.role ?? this.wrapped.role; }
|
|
111
|
+
|
|
112
|
+
get icon(): string | undefined { return this.iconClass; }
|
|
113
|
+
|
|
114
|
+
get iconClass(): string | undefined { return this.options?.iconClass ?? this.wrapped.iconClass; }
|
|
115
|
+
|
|
116
|
+
get order(): string | undefined { return this.options?.order ?? this.wrapped.order; }
|
|
117
|
+
|
|
118
|
+
get when(): string | undefined { return this.options?.when ?? this.wrapped.when; }
|
|
119
|
+
|
|
120
|
+
get children(): ReadonlyArray<MenuNode> { return this.wrapped.children; }
|
|
121
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
export * from './action-menu-node';
|
|
18
|
+
export * from './composite-menu-node';
|
|
19
|
+
export * from './menu-adapter';
|
|
20
|
+
export * from './menu-model-registry';
|
|
21
|
+
export * from './menu-types';
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2022 Ericsson and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { inject, injectable } from 'inversify';
|
|
18
|
+
import { CommandRegistry } from '../command';
|
|
19
|
+
import { Disposable } from '../disposable';
|
|
20
|
+
import { MenuPath } from './menu-types';
|
|
21
|
+
|
|
22
|
+
export type MenuCommandArguments = [menuPath: MenuPath, command: string, ...commandArgs: unknown[]];
|
|
23
|
+
|
|
24
|
+
export const MenuCommandExecutor = Symbol('MenuCommandExecutor');
|
|
25
|
+
export interface MenuCommandExecutor {
|
|
26
|
+
isVisible(...args: MenuCommandArguments): boolean;
|
|
27
|
+
isEnabled(...args: MenuCommandArguments): boolean;
|
|
28
|
+
isToggled(...args: MenuCommandArguments): boolean;
|
|
29
|
+
executeCommand(...args: MenuCommandArguments): Promise<unknown>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export const MenuCommandAdapter = Symbol('MenuCommandAdapter');
|
|
33
|
+
export interface MenuCommandAdapter extends MenuCommandExecutor {
|
|
34
|
+
/** Return values less than or equal to 0 are treated as rejections. */
|
|
35
|
+
canHandle(...args: MenuCommandArguments): number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export const MenuCommandAdapterRegistry = Symbol('MenuCommandAdapterRegistry');
|
|
39
|
+
export interface MenuCommandAdapterRegistry {
|
|
40
|
+
registerAdapter(adapter: MenuCommandAdapter): Disposable;
|
|
41
|
+
getAdapterFor(...args: MenuCommandArguments): MenuCommandAdapter | undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@injectable()
|
|
45
|
+
export class MenuCommandExecutorImpl implements MenuCommandExecutor {
|
|
46
|
+
@inject(MenuCommandAdapterRegistry) protected readonly adapterRegistry: MenuCommandAdapterRegistry;
|
|
47
|
+
@inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
|
|
48
|
+
|
|
49
|
+
executeCommand(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): Promise<unknown> {
|
|
50
|
+
return this.delegate(menuPath, command, commandArgs, 'executeCommand');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
isVisible(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
54
|
+
return this.delegate(menuPath, command, commandArgs, 'isVisible');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
isEnabled(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
58
|
+
return this.delegate(menuPath, command, commandArgs, 'isEnabled');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
isToggled(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): boolean {
|
|
62
|
+
return this.delegate(menuPath, command, commandArgs, 'isToggled');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
protected delegate<T extends keyof MenuCommandExecutor>(menuPath: MenuPath, command: string, commandArgs: unknown[], method: T): ReturnType<MenuCommandExecutor[T]> {
|
|
66
|
+
const adapter = this.adapterRegistry.getAdapterFor(menuPath, command, commandArgs);
|
|
67
|
+
return (adapter
|
|
68
|
+
? adapter[method](menuPath, command, ...commandArgs)
|
|
69
|
+
: this.commandRegistry[method](command, ...commandArgs)) as ReturnType<MenuCommandExecutor[T]>;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@injectable()
|
|
74
|
+
export class MenuCommandAdapterRegistryImpl implements MenuCommandAdapterRegistry {
|
|
75
|
+
protected readonly adapters = new Array<MenuCommandAdapter>();
|
|
76
|
+
|
|
77
|
+
registerAdapter(adapter: MenuCommandAdapter): Disposable {
|
|
78
|
+
if (!this.adapters.includes(adapter)) {
|
|
79
|
+
this.adapters.push(adapter);
|
|
80
|
+
return Disposable.create(() => {
|
|
81
|
+
const index = this.adapters.indexOf(adapter);
|
|
82
|
+
if (index !== -1) {
|
|
83
|
+
this.adapters.splice(index, 1);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return Disposable.NULL;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
getAdapterFor(menuPath: MenuPath, command: string, ...commandArgs: unknown[]): MenuCommandAdapter | undefined {
|
|
91
|
+
let bestAdapter: MenuCommandAdapter | undefined = undefined;
|
|
92
|
+
let bestScore = 0;
|
|
93
|
+
let currentScore = 0;
|
|
94
|
+
for (const adapter of this.adapters) {
|
|
95
|
+
// Greater than or equal: favor later registrations over earlier.
|
|
96
|
+
if ((currentScore = adapter.canHandle(menuPath, command, ...commandArgs)) >= bestScore) {
|
|
97
|
+
bestScore = currentScore;
|
|
98
|
+
bestAdapter = adapter;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return bestAdapter;
|
|
102
|
+
}
|
|
103
|
+
}
|