Skip to content

Commit 23e0bec

Browse files
tsmaederdhuebner
andauthored
Refactor menu nodes (#14676)
Fixes #14217 Makes menu nodes active object that can decide on visibility, enablement, etc. themselves. Contributed on behalf of STMicroelectronics Signed-off-by: Thomas Mäder <[email protected]> Co-authored-by: Dennis Huebner <[email protected]>
1 parent a2052f0 commit 23e0bec

File tree

78 files changed

+2060
-2330
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2060
-2330
lines changed

.vscode/launch.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"name": "Playwright Tests",
9+
"type": "node",
10+
"request": "launch",
11+
"program": "${workspaceFolder}/node_modules/@playwright/test/cli.js",
12+
"cwd": "${workspaceFolder}/examples/playwright",
13+
"args": [
14+
"test",
15+
"--config=./configs/playwright.config.ts"
16+
]
17+
},
718
{
819
"type": "node",
920
"request": "attach",

CHANGELOG.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44

55
- [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/)
66

7+
## 1.62.0 -
8+
9+
10+
<a name="breaking_changes_1.62.0">[Breaking Changes:](#breaking_changes_1.62.0)</a>
11+
12+
- [core] Refactor menu nodes [#14676](https://github.com/eclipse-theia/theia/pull/14676) - Contributed on behalf of STMicroelectronics
13+
14+
715
## 1.61.0 - 4/29/2025
816

917
- [ai-anthropic] fix: do not set anthropic tool choice without tools [#15329](https://github.com/eclipse-theia/theia/pull/15329)
@@ -199,11 +207,14 @@
199207
<a name="breaking_changes_1.60.0">[Breaking Changes:](#breaking_changes_1.60.0)</a>
200208

201209
- [core] fixed version `@types/express` to `^4.17.21` and `@types/express-serve-static-core` to `5.0.4`. This might be required for adopters as well if they run into typing issues. [#15147](https://github.com/eclipse-theia/theia/pull/15147)
202-
- [core] migrated from deprecated `phosphorJs` to `Lumino`; adopters must update imports from `@phosphor` to `@lumino`, adjust CSS selectors from `.p-` to `.lm-`, and make minor code changes such as replacing `icon` with `iconClass` in commands [#14320](https://github.com/eclipse-theia/theia/pull/14320) - Contributed on behalf of STMicroelectronics
203-
- [core] corrected typing of `addKeyListener` and `Widget.addKeyListener` to reflect events for `additionalEventTypes`; adopters explicitly expecting `KeyboardEvent` may need to update type declarations [#15210](https://github.com/eclipse-theia/theia/pull/15210)
204-
- [ai] changed the format of `ai-features.modelSettings.requestSettings`; also improved message types and updated the request object for LLMs [#15092](https://github.com/eclipse-theia/theia/pull/15092)
205-
- [ai-chat] changed `ParsedChatRequest.variables` to be `ResolvedAIVariable[]` instead of `Map<string, AIVariable>` [#15196](https://github.com/eclipse-theia/theia/pull/15196)
206-
- [ai-chat] made `ChatRequestParser.parseChatRequest` asynchronous and added a `ChatContext` parameter [#15196](https://github.com/eclipse-theia/theia/pull/15196)
210+
- [core] migration from deprecated `phosphorJs` to actively maintained fork `Lumino` [#14320](https://github.com/eclipse-theia/theia/pull/14320) - Contributed on behalf of STMicroelectronics
211+
Adopters importing `@phosphor` packages now need to import from `@lumino`. CSS selectors refering to `.p-` classes now need to refer to `.lm-` classes. There are also minor code adaptations, for example now using `iconClass` instead of `icon` in Lumino commands.
212+
- [core] Refactor menu nodes [#14676](https://github.com/eclipse-theia/theia/pull/14676) - Contributed on behalf of STMicroelectronics
213+
214+
<a name="breaking_changes_1.60.0">[Breaking Changes:](#breaking_changes_1.60.0)</a>
215+
216+
- [ai-chat] `ParsedChatRequest.variables` is now `ResolvedAIVariable[]` instead of a `Map<string, AIVariable>` [#15196](https://github.com/eclipse-theia/theia/pull/15196)
217+
- [ai-chat] `ChatRequestParser.parseChatRequest` is now asynchronous and expects an additional `ChatContext` parameter [#15196](https://github.com/eclipse-theia/theia/pull/15196)
207218

208219
## 1.59.0 - 02/27/2025
209220

doc/Migration.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ For example:
5959
}
6060
```
6161

62+
### v1.62.0
63+
64+
#### Refactor menu nodes [#14676](https://github.com/eclipse-theia/theia/pull/14676)
65+
66+
This PR makes menu nodes and tab toolbar items into active object instead of pure data descriptors. This means they can polymorphically handle concerns like enablement, visibility, command execution and rendering. This keeps concerns like conversion of parameters out of the general tool bar and menu handling code. In this way, we could get rid of the MenuCommandExecutor and MenuCommandAdapter infrastructure.
67+
If you are simply registering toolbar items and menus, little will change for you as a Theia adopter. Mainly, some of the paremeter types have changed in menu-model-registry.ts. Menu registration has been simplified in that an independent submenu is simply a menu that is registered under a path that does not start with the MAIN_MENU_BAR prefix.
68+
If you override any of the toolbar or menu related implementations in your product, the biggest change will be that some functionality is now delegated to the menu and too bar item implementations. If this breaks your use case, please let us know.
69+
6270
### v1.38.0
6371

6472
#### Inversify 6.0

examples/api-samples/package.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@
2525
"frontend": "lib/browser/api-samples-frontend-module",
2626
"backend": "lib/node/api-samples-backend-module"
2727
},
28-
{
29-
"frontend": "lib/browser/menu/sample-browser-menu-module",
30-
"frontendElectron": "lib/electron-browser/menu/sample-electron-menu-module"
31-
},
3228
{
3329
"electronMain": "lib/electron-main/update/sample-updater-main-module",
3430
"frontendElectron": "lib/electron-browser/updater/sample-updater-frontend-module"
@@ -65,4 +61,4 @@
6561
"devDependencies": {
6662
"@theia/ext-scripts": "1.61.0"
6763
}
68-
}
64+
}

examples/api-samples/src/browser/menu/sample-browser-menu-module.ts

Lines changed: 0 additions & 98 deletions
This file was deleted.

examples/api-samples/src/browser/menu/sample-menu-contribution.ts

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import { ConfirmDialog, Dialog, QuickInputService } from '@theia/core/lib/browse
1818
import { ReactDialog } from '@theia/core/lib/browser/dialogs/react-dialog';
1919
import { SelectComponent } from '@theia/core/lib/browser/widgets/select-component';
2020
import {
21-
Command, CommandContribution, CommandRegistry, MAIN_MENU_BAR,
22-
MenuContribution, MenuModelRegistry, MenuNode, MessageService, SubMenuOptions
21+
Command, CommandContribution, CommandMenu, CommandRegistry, ContextExpressionMatcher, MAIN_MENU_BAR,
22+
MenuContribution, MenuModelRegistry, MenuPath, MessageService
2323
} from '@theia/core/lib/common';
2424
import { inject, injectable, interfaces } from '@theia/core/shared/inversify';
2525
import * as React from '@theia/core/shared/react';
@@ -227,9 +227,8 @@ export class SampleMenuContribution implements MenuContribution {
227227
registerMenus(menus: MenuModelRegistry): void {
228228
setTimeout(() => {
229229
const subMenuPath = [...MAIN_MENU_BAR, 'sample-menu'];
230-
menus.registerSubmenu(subMenuPath, 'Sample Menu', {
231-
order: '2' // that should put the menu right next to the File menu
232-
});
230+
menus.registerSubmenu(subMenuPath, 'Sample Menu', { sortString: '2' }); // that should put the menu right next to the File menu
231+
233232
menus.registerMenuAction(subMenuPath, {
234233
commandId: SampleCommand.id,
235234
order: '0'
@@ -239,7 +238,7 @@ export class SampleMenuContribution implements MenuContribution {
239238
order: '2'
240239
});
241240
const subSubMenuPath = [...subMenuPath, 'sample-sub-menu'];
242-
menus.registerSubmenu(subSubMenuPath, 'Sample sub menu', { order: '2' });
241+
menus.registerSubmenu(subSubMenuPath, 'Sample sub menu', { sortString: '2' });
243242
menus.registerMenuAction(subSubMenuPath, {
244243
commandId: SampleCommand.id,
245244
order: '1'
@@ -248,8 +247,8 @@ export class SampleMenuContribution implements MenuContribution {
248247
commandId: SampleCommand2.id,
249248
order: '3'
250249
});
251-
const placeholder = new PlaceholderMenuNode([...subSubMenuPath, 'placeholder'].join('-'), 'Placeholder', { order: '0' });
252-
menus.registerMenuNode(subSubMenuPath, placeholder);
250+
const placeholder = new PlaceholderMenuNode([...subSubMenuPath, 'placeholder'].join('-'), 'Placeholder', '0');
251+
menus.registerCommandMenu(subSubMenuPath, placeholder);
253252

254253
/**
255254
* Register an action menu with an invalid command (un-registered and without a label) in order
@@ -258,22 +257,35 @@ export class SampleMenuContribution implements MenuContribution {
258257
menus.registerMenuAction(subMenuPath, { commandId: 'invalid-command' });
259258
}, 10000);
260259
}
261-
262260
}
263261

264262
/**
265263
* Special menu node that is not backed by any commands and is always disabled.
266264
*/
267-
export class PlaceholderMenuNode implements MenuNode {
265+
export class PlaceholderMenuNode implements CommandMenu {
268266

269-
constructor(readonly id: string, public readonly label: string, protected options?: SubMenuOptions) { }
267+
constructor(readonly id: string, public readonly label: string, readonly order?: string, readonly icon?: string) { }
270268

271-
get icon(): string | undefined {
272-
return this.options?.iconClass;
269+
isEnabled(effectiveMenuPath: MenuPath, ...args: unknown[]): boolean {
270+
return false;
271+
}
272+
273+
isToggled(effectiveMenuPath: MenuPath): boolean {
274+
return false;
275+
}
276+
run(effectiveMenuPath: MenuPath, ...args: unknown[]): Promise<void> {
277+
throw new Error('Should never happen');
278+
}
279+
getAccelerator(context: HTMLElement | undefined): string[] {
280+
return [];
273281
}
274282

275283
get sortString(): string {
276-
return this.options?.order || this.label;
284+
return this.order || this.label;
285+
}
286+
287+
isVisible<T>(effectiveMenuPath: MenuPath, contextMatcher: ContextExpressionMatcher<T>, context: T | undefined, ...args: unknown[]): boolean {
288+
return true;
277289
}
278290

279291
}

examples/api-samples/src/electron-browser/menu/sample-electron-menu-module.ts

Lines changed: 0 additions & 42 deletions
This file was deleted.

examples/playwright/src/theia-notebook-editor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ export class TheiaNotebookEditor extends TheiaEditor {
4949
}
5050

5151
tabLocator(): Locator {
52-
return this.page.locator(this.data.viewSelector);
52+
return this.page.locator(this.data.tabSelector);
5353
}
5454

5555
override async waitForVisible(): Promise<void> {

examples/playwright/src/theia-toolbar-item.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export class TheiaToolbarItem extends TheiaPageObject {
2828
}
2929

3030
async isEnabled(): Promise<boolean> {
31-
const classAttribute = await this.element.getAttribute('class');
31+
const child = await this.element.$(':first-child');
32+
const classAttribute = child && await child.getAttribute('class');
3233
if (classAttribute === undefined || classAttribute === null) {
3334
return false;
3435
}

0 commit comments

Comments
 (0)