@theia/core 1.61.0 → 1.62.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.
Files changed (244) hide show
  1. package/README.md +7 -7
  2. package/i18n/nls.cs.json +158 -13
  3. package/i18n/nls.de.json +158 -13
  4. package/i18n/nls.es.json +158 -13
  5. package/i18n/nls.fr.json +158 -13
  6. package/i18n/nls.hu.json +158 -13
  7. package/i18n/nls.it.json +158 -13
  8. package/i18n/nls.ja.json +158 -13
  9. package/i18n/nls.json +159 -14
  10. package/i18n/nls.ko.json +158 -13
  11. package/i18n/nls.pl.json +158 -13
  12. package/i18n/nls.pt-br.json +158 -13
  13. package/i18n/nls.ru.json +158 -13
  14. package/i18n/nls.tr.json +158 -13
  15. package/i18n/nls.zh-cn.json +158 -13
  16. package/i18n/nls.zh-tw.json +158 -13
  17. package/lib/browser/catalog.json +197 -33
  18. package/lib/browser/common-frontend-contribution.d.ts +1 -1
  19. package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
  20. package/lib/browser/common-frontend-contribution.js +13 -11
  21. package/lib/browser/common-frontend-contribution.js.map +1 -1
  22. package/lib/browser/context-menu-renderer.d.ts +14 -3
  23. package/lib/browser/context-menu-renderer.d.ts.map +1 -1
  24. package/lib/browser/context-menu-renderer.js +23 -1
  25. package/lib/browser/context-menu-renderer.js.map +1 -1
  26. package/lib/browser/frontend-application-module.d.ts.map +1 -1
  27. package/lib/browser/frontend-application-module.js +1 -3
  28. package/lib/browser/frontend-application-module.js.map +1 -1
  29. package/lib/browser/hover-service.d.ts.map +1 -1
  30. package/lib/browser/hover-service.js +7 -0
  31. package/lib/browser/hover-service.js.map +1 -1
  32. package/lib/browser/menu/action-menu-node.d.ts +36 -0
  33. package/lib/browser/menu/action-menu-node.d.ts.map +1 -0
  34. package/lib/browser/menu/action-menu-node.js +113 -0
  35. package/lib/browser/menu/action-menu-node.js.map +1 -0
  36. package/lib/browser/menu/browser-context-menu-renderer.d.ts +12 -4
  37. package/lib/browser/menu/browser-context-menu-renderer.d.ts.map +1 -1
  38. package/lib/browser/menu/browser-context-menu-renderer.js +12 -13
  39. package/lib/browser/menu/browser-context-menu-renderer.js.map +1 -1
  40. package/lib/browser/menu/browser-menu-module.d.ts.map +1 -1
  41. package/lib/browser/menu/browser-menu-module.js +4 -0
  42. package/lib/browser/menu/browser-menu-module.js.map +1 -1
  43. package/lib/browser/menu/browser-menu-node-factory.d.ts +13 -0
  44. package/lib/browser/menu/browser-menu-node-factory.d.ts.map +1 -0
  45. package/lib/browser/menu/browser-menu-node-factory.js +54 -0
  46. package/lib/browser/menu/browser-menu-node-factory.js.map +1 -0
  47. package/lib/browser/menu/browser-menu-plugin.d.ts +12 -30
  48. package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
  49. package/lib/browser/menu/browser-menu-plugin.js +78 -159
  50. package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
  51. package/lib/browser/menu/composite-menu-node.d.ts +49 -0
  52. package/lib/browser/menu/composite-menu-node.d.ts.map +1 -0
  53. package/lib/browser/menu/composite-menu-node.js +127 -0
  54. package/lib/browser/menu/composite-menu-node.js.map +1 -0
  55. package/lib/browser/menu/menu.spec.d.ts.map +1 -0
  56. package/lib/{common → browser}/menu/menu.spec.js +38 -13
  57. package/lib/browser/menu/menu.spec.js.map +1 -0
  58. package/lib/browser/open-with-service.d.ts +1 -1
  59. package/lib/browser/saveable-service.d.ts.map +1 -1
  60. package/lib/browser/saveable-service.js +6 -1
  61. package/lib/browser/saveable-service.js.map +1 -1
  62. package/lib/browser/shell/application-shell.d.ts +7 -5
  63. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  64. package/lib/browser/shell/application-shell.js +82 -28
  65. package/lib/browser/shell/application-shell.js.map +1 -1
  66. package/lib/browser/shell/index.d.ts +1 -0
  67. package/lib/browser/shell/index.d.ts.map +1 -1
  68. package/lib/browser/shell/index.js +1 -0
  69. package/lib/browser/shell/index.js.map +1 -1
  70. package/lib/browser/shell/sidebar-bottom-menu-widget.d.ts.map +1 -1
  71. package/lib/browser/shell/sidebar-bottom-menu-widget.js +2 -1
  72. package/lib/browser/shell/sidebar-bottom-menu-widget.js.map +1 -1
  73. package/lib/browser/shell/sidebar-menu-widget.d.ts +4 -1
  74. package/lib/browser/shell/sidebar-menu-widget.d.ts.map +1 -1
  75. package/lib/browser/shell/sidebar-menu-widget.js +14 -1
  76. package/lib/browser/shell/sidebar-menu-widget.js.map +1 -1
  77. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts +66 -8
  78. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts.map +1 -1
  79. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +161 -8
  80. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -1
  81. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts +18 -32
  82. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts.map +1 -1
  83. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +52 -88
  84. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -1
  85. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts +17 -21
  86. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.d.ts.map +1 -1
  87. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js +9 -9
  88. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.js.map +1 -1
  89. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts +7 -39
  90. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.d.ts.map +1 -1
  91. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js +30 -238
  92. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.js.map +1 -1
  93. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js +13 -13
  94. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.js.map +1 -1
  95. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts +56 -0
  96. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts.map +1 -0
  97. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js +208 -0
  98. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.js.map +1 -0
  99. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  100. package/lib/browser/shell/tab-bars.js +2 -1
  101. package/lib/browser/shell/tab-bars.js.map +1 -1
  102. package/lib/browser/shell/theia-dock-panel.d.ts +4 -10
  103. package/lib/browser/shell/theia-dock-panel.d.ts.map +1 -1
  104. package/lib/browser/shell/theia-dock-panel.js +7 -84
  105. package/lib/browser/shell/theia-dock-panel.js.map +1 -1
  106. package/lib/browser/shell/theia-split-panel.d.ts +6 -0
  107. package/lib/browser/shell/theia-split-panel.d.ts.map +1 -0
  108. package/lib/browser/shell/theia-split-panel.js +56 -0
  109. package/lib/browser/shell/theia-split-panel.js.map +1 -0
  110. package/lib/browser/tree/tree-widget.d.ts +1 -0
  111. package/lib/browser/tree/tree-widget.d.ts.map +1 -1
  112. package/lib/browser/tree/tree-widget.js +6 -0
  113. package/lib/browser/tree/tree-widget.js.map +1 -1
  114. package/lib/browser/view-container.d.ts +6 -3
  115. package/lib/browser/view-container.d.ts.map +1 -1
  116. package/lib/browser/view-container.js +36 -26
  117. package/lib/browser/view-container.js.map +1 -1
  118. package/lib/browser/window/default-secondary-window-service.d.ts +1 -0
  119. package/lib/browser/window/default-secondary-window-service.d.ts.map +1 -1
  120. package/lib/browser/window/default-secondary-window-service.js +3 -0
  121. package/lib/browser/window/default-secondary-window-service.js.map +1 -1
  122. package/lib/common/listener.d.ts +21 -0
  123. package/lib/common/listener.d.ts.map +1 -0
  124. package/lib/common/listener.js +81 -0
  125. package/lib/common/listener.js.map +1 -0
  126. package/lib/common/listener.spec.d.ts +2 -0
  127. package/lib/common/listener.spec.d.ts.map +1 -0
  128. package/lib/common/listener.spec.js +255 -0
  129. package/lib/common/listener.spec.js.map +1 -0
  130. package/lib/common/menu/index.d.ts +2 -3
  131. package/lib/common/menu/index.d.ts.map +1 -1
  132. package/lib/common/menu/index.js +2 -3
  133. package/lib/common/menu/index.js.map +1 -1
  134. package/lib/common/menu/menu-model-registry.d.ts +37 -50
  135. package/lib/common/menu/menu-model-registry.d.ts.map +1 -1
  136. package/lib/common/menu/menu-model-registry.js +176 -225
  137. package/lib/common/menu/menu-model-registry.js.map +1 -1
  138. package/lib/common/menu/menu-types.d.ts +58 -96
  139. package/lib/common/menu/menu-types.d.ts.map +1 -1
  140. package/lib/common/menu/menu-types.js +43 -39
  141. package/lib/common/menu/menu-types.js.map +1 -1
  142. package/lib/common/messaging/proxy-factory.d.ts.map +1 -1
  143. package/lib/common/messaging/proxy-factory.js +4 -0
  144. package/lib/common/messaging/proxy-factory.js.map +1 -1
  145. package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts +15 -5
  146. package/lib/electron-browser/menu/electron-context-menu-renderer.d.ts.map +1 -1
  147. package/lib/electron-browser/menu/electron-context-menu-renderer.js +21 -14
  148. package/lib/electron-browser/menu/electron-context-menu-renderer.js.map +1 -1
  149. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts +4 -16
  150. package/lib/electron-browser/menu/electron-main-menu-factory.d.ts.map +1 -1
  151. package/lib/electron-browser/menu/electron-main-menu-factory.js +84 -104
  152. package/lib/electron-browser/menu/electron-main-menu-factory.js.map +1 -1
  153. package/lib/electron-browser/menu/electron-menu-contribution.d.ts.map +1 -1
  154. package/lib/electron-browser/menu/electron-menu-contribution.js +1 -4
  155. package/lib/electron-browser/menu/electron-menu-contribution.js.map +1 -1
  156. package/lib/electron-browser/menu/electron-menu-module.d.ts.map +1 -1
  157. package/lib/electron-browser/menu/electron-menu-module.js +5 -0
  158. package/lib/electron-browser/menu/electron-menu-module.js.map +1 -1
  159. package/lib/electron-browser/window/electron-secondary-window-service.d.ts +1 -0
  160. package/lib/electron-browser/window/electron-secondary-window-service.d.ts.map +1 -1
  161. package/lib/electron-browser/window/electron-secondary-window-service.js +20 -0
  162. package/lib/electron-browser/window/electron-secondary-window-service.js.map +1 -1
  163. package/lib/electron-browser/window/electron-window-service.d.ts +3 -0
  164. package/lib/electron-browser/window/electron-window-service.d.ts.map +1 -1
  165. package/lib/electron-browser/window/electron-window-service.js +10 -1
  166. package/lib/electron-browser/window/electron-window-service.js.map +1 -1
  167. package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
  168. package/lib/electron-main/theia-electron-window.js +2 -0
  169. package/lib/electron-main/theia-electron-window.js.map +1 -1
  170. package/package.json +7 -8
  171. package/src/browser/common-frontend-contribution.ts +14 -14
  172. package/src/browser/context-menu-renderer.ts +33 -5
  173. package/src/browser/frontend-application-module.ts +1 -7
  174. package/src/browser/hover-service.ts +7 -0
  175. package/src/browser/menu/action-menu-node.ts +128 -0
  176. package/src/browser/menu/browser-context-menu-renderer.ts +18 -11
  177. package/src/browser/menu/browser-menu-module.ts +4 -0
  178. package/src/browser/menu/browser-menu-node-factory.ts +48 -0
  179. package/src/browser/menu/browser-menu-plugin.ts +80 -168
  180. package/src/browser/menu/composite-menu-node.ts +140 -0
  181. package/src/{common → browser}/menu/menu.spec.ts +47 -15
  182. package/src/browser/open-with-service.ts +1 -1
  183. package/src/browser/saveable-service.ts +6 -1
  184. package/src/browser/shell/application-shell.ts +91 -29
  185. package/src/browser/shell/index.ts +1 -0
  186. package/src/browser/shell/sidebar-bottom-menu-widget.tsx +2 -1
  187. package/src/browser/shell/sidebar-menu-widget.tsx +12 -2
  188. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.tsx +239 -0
  189. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +59 -102
  190. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-types.ts +14 -23
  191. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.spec.ts +14 -14
  192. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar.tsx +34 -261
  193. package/src/browser/shell/tab-bar-toolbar/tab-toolbar-item.tsx +251 -0
  194. package/src/browser/shell/tab-bars.ts +2 -1
  195. package/src/browser/shell/theia-dock-panel.ts +10 -91
  196. package/src/browser/shell/theia-split-panel.ts +56 -0
  197. package/src/browser/style/hover-service.css +6 -1
  198. package/src/browser/style/index.css +3 -11
  199. package/src/browser/style/view-container.css +17 -31
  200. package/src/browser/tree/tree-widget.tsx +7 -0
  201. package/src/browser/view-container.ts +51 -30
  202. package/src/browser/window/default-secondary-window-service.ts +4 -0
  203. package/src/common/listener.spec.ts +315 -0
  204. package/src/common/listener.ts +88 -0
  205. package/src/common/menu/index.ts +2 -3
  206. package/src/common/menu/menu-model-registry.ts +187 -230
  207. package/src/common/menu/menu-types.ts +82 -128
  208. package/src/common/messaging/proxy-factory.ts +4 -1
  209. package/src/electron-browser/menu/electron-context-menu-renderer.ts +29 -13
  210. package/src/electron-browser/menu/electron-main-menu-factory.ts +92 -116
  211. package/src/electron-browser/menu/electron-menu-contribution.ts +1 -4
  212. package/src/electron-browser/menu/electron-menu-module.ts +6 -1
  213. package/src/electron-browser/window/electron-secondary-window-service.ts +22 -0
  214. package/src/electron-browser/window/electron-window-service.ts +11 -1
  215. package/src/electron-main/theia-electron-window.ts +2 -0
  216. package/lib/common/menu/action-menu-node.d.ts +0 -20
  217. package/lib/common/menu/action-menu-node.d.ts.map +0 -1
  218. package/lib/common/menu/action-menu-node.js +0 -57
  219. package/lib/common/menu/action-menu-node.js.map +0 -1
  220. package/lib/common/menu/composite-menu-node.d.ts +0 -47
  221. package/lib/common/menu/composite-menu-node.d.ts.map +0 -1
  222. package/lib/common/menu/composite-menu-node.js +0 -96
  223. package/lib/common/menu/composite-menu-node.js.map +0 -1
  224. package/lib/common/menu/composite-menu-node.spec.d.ts +0 -2
  225. package/lib/common/menu/composite-menu-node.spec.d.ts.map +0 -1
  226. package/lib/common/menu/composite-menu-node.spec.js +0 -68
  227. package/lib/common/menu/composite-menu-node.spec.js.map +0 -1
  228. package/lib/common/menu/menu-adapter.d.ts +0 -36
  229. package/lib/common/menu/menu-adapter.d.ts.map +0 -1
  230. package/lib/common/menu/menu-adapter.js +0 -93
  231. package/lib/common/menu/menu-adapter.js.map +0 -1
  232. package/lib/common/menu/menu.spec.d.ts.map +0 -1
  233. package/lib/common/menu/menu.spec.js.map +0 -1
  234. package/lib/common/test/mock-menu.d.ts +0 -8
  235. package/lib/common/test/mock-menu.d.ts.map +0 -1
  236. package/lib/common/test/mock-menu.js +0 -35
  237. package/lib/common/test/mock-menu.js.map +0 -1
  238. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.ts +0 -31
  239. package/src/common/menu/action-menu-node.ts +0 -65
  240. package/src/common/menu/composite-menu-node.spec.ts +0 -67
  241. package/src/common/menu/composite-menu-node.ts +0 -116
  242. package/src/common/menu/menu-adapter.ts +0 -103
  243. package/src/common/test/mock-menu.ts +0 -35
  244. /package/lib/{common → browser}/menu/menu.spec.d.ts +0 -0
@@ -34,7 +34,7 @@ import { FrontendApplicationStateService } from '../frontend-application-state';
34
34
  import { TabBarToolbarRegistry, TabBarToolbarFactory } from './tab-bar-toolbar';
35
35
  import { ContextKeyService } from '../context-key-service';
36
36
  import { Emitter } from '../../common/event';
37
- import { waitForRevealed, waitForClosed, PINNED_CLASS } from '../widgets';
37
+ import { waitForRevealed, waitForClosed, PINNED_CLASS, UnsafeWidgetUtilities } from '../widgets';
38
38
  import { CorePreferences } from '../core-preferences';
39
39
  import { BreadcrumbsRendererFactory } from '../breadcrumbs/breadcrumbs-renderer';
40
40
  import { Deferred } from '../../common/promise-util';
@@ -45,6 +45,7 @@ import URI from '../../common/uri';
45
45
  import { OpenerService } from '../opener-service';
46
46
  import { PreviewableWidget } from '../widgets/previewable-widget';
47
47
  import { WindowService } from '../window/window-service';
48
+ import { TheiaSplitPanel } from './theia-split-panel';
48
49
 
49
50
  /** The class name added to ApplicationShell instances. */
50
51
  export const APPLICATION_SHELL_CLASS = 'theia-ApplicationShell';
@@ -85,10 +86,6 @@ export interface DockPanelRendererFactory {
85
86
  */
86
87
  @injectable()
87
88
  export class DockPanelRenderer implements DockLayout.IRenderer {
88
-
89
- @inject(TheiaDockPanel.Factory)
90
- protected readonly dockPanelFactory: TheiaDockPanel.Factory;
91
-
92
89
  readonly tabBarClasses: string[] = [];
93
90
 
94
91
  private readonly onDidCreateTabBarEmitter = new Emitter<TabBar<Widget>>();
@@ -175,6 +172,7 @@ interface WidgetDragState {
175
172
  leaveTimeout?: number;
176
173
  }
177
174
 
175
+ export const MAXIMIZED_CLASS = 'theia-maximized';
178
176
  /**
179
177
  * The application shell manages the top-level widgets of the application. Use this class to
180
178
  * add, remove, or activate a widget.
@@ -269,6 +267,8 @@ export class ApplicationShell extends Widget {
269
267
  protected initializedDeferred = new Deferred<void>();
270
268
  initialized = this.initializedDeferred.promise;
271
269
 
270
+ protected readonly maximizedElement: HTMLElement;
271
+
272
272
  /**
273
273
  * Construct a new application shell.
274
274
  */
@@ -286,6 +286,16 @@ export class ApplicationShell extends Widget {
286
286
  ) {
287
287
  super(options as Widget.IOptions);
288
288
 
289
+ this.maximizedElement = this.node.ownerDocument.createElement('div');
290
+ this.maximizedElement.style.position = 'fixed';
291
+ this.maximizedElement.style.display = 'none';
292
+ this.maximizedElement.style.left = '0px';
293
+ this.maximizedElement.style.bottom = '0px';
294
+ this.maximizedElement.style.right = '0px';
295
+ this.maximizedElement.style.background = 'var(--theia-editor-background)';
296
+ this.maximizedElement.style.zIndex = '2000';
297
+ this.node.ownerDocument.body.appendChild(this.maximizedElement);
298
+
289
299
  // Merge the user-defined application options with the default options
290
300
  this.options = {
291
301
  bottomPanel: {
@@ -301,6 +311,13 @@ export class ApplicationShell extends Widget {
301
311
  ...options?.rightPanel || {}
302
312
  }
303
313
  };
314
+ if (corePreferences) {
315
+ corePreferences.onPreferenceChanged(preference => {
316
+ if (preference.preferenceName === 'window.menuBarVisibility' && (preference.newValue === 'visible' || preference.oldValue === 'visible')) {
317
+ this.handleMenuBarVisibility(preference.newValue);
318
+ }
319
+ });
320
+ }
304
321
  }
305
322
 
306
323
  @postConstruct()
@@ -561,7 +578,7 @@ export class ApplicationShell extends Widget {
561
578
  mode: 'multiple-document',
562
579
  renderer,
563
580
  spacing: 0
564
- });
581
+ }, area => this.doToggleMaximized(area));
565
582
  dockPanel.id = MAIN_AREA_ID;
566
583
  dockPanel.widgetAdded.connect((_, widget) => this.fireDidAddWidget(widget));
567
584
  dockPanel.widgetRemoved.connect((_, widget) => this.fireDidRemoveWidget(widget));
@@ -658,7 +675,7 @@ export class ApplicationShell extends Widget {
658
675
  mode: 'multiple-document',
659
676
  renderer,
660
677
  spacing: 0
661
- });
678
+ }, area => this.doToggleMaximized(area));
662
679
  dockPanel.id = BOTTOM_AREA_ID;
663
680
  dockPanel.widgetAdded.connect((sender, widget) => {
664
681
  this.refreshBottomPanelToggleButton();
@@ -731,7 +748,7 @@ export class ApplicationShell extends Widget {
731
748
  [1, 0],
732
749
  { orientation: 'vertical', spacing: 0 }
733
750
  );
734
- const panelForBottomArea = new SplitPanel({ layout: bottomSplitLayout });
751
+ const panelForBottomArea = new TheiaSplitPanel({ layout: bottomSplitLayout });
735
752
  panelForBottomArea.id = 'theia-bottom-split-panel';
736
753
 
737
754
  const leftRightSplitLayout = this.createSplitLayout(
@@ -739,7 +756,7 @@ export class ApplicationShell extends Widget {
739
756
  [0, 1, 0],
740
757
  { orientation: 'horizontal', spacing: 0 }
741
758
  );
742
- const panelForSideAreas = new SplitPanel({ layout: leftRightSplitLayout });
759
+ const panelForSideAreas = new TheiaSplitPanel({ layout: leftRightSplitLayout });
743
760
  panelForSideAreas.id = 'theia-left-right-split-panel';
744
761
 
745
762
  return this.createBoxLayout(
@@ -1178,9 +1195,6 @@ export class ApplicationShell extends Widget {
1178
1195
  w.title.className = w.title.className.replace(' theia-mod-active', '');
1179
1196
  w = w.parent;
1180
1197
  }
1181
- // Reset the z-index to the default
1182
- // eslint-disable-next-line no-null/no-null
1183
- this.setZIndex(oldValue.node, null);
1184
1198
  }
1185
1199
  if (newValue) {
1186
1200
  let w: Widget | null = newValue;
@@ -1203,11 +1217,6 @@ export class ApplicationShell extends Widget {
1203
1217
  // if widget was undefined, we wouldn't have gotten a panel back before
1204
1218
  panel.markAsCurrent(widget!.title);
1205
1219
  }
1206
- // Add checks to ensure that the 'sash' for left panel is displayed correctly
1207
- if (newValue.node.className === 'lm-Widget theia-view-container lm-DockPanel-widget') {
1208
- // Set the z-index so elements with `position: fixed` contained in the active widget are displayed correctly
1209
- this.setZIndex(newValue.node, '1');
1210
- }
1211
1220
 
1212
1221
  // activate another widget if an active widget will be closed
1213
1222
  const onCloseRequest = newValue['onCloseRequest'];
@@ -1237,17 +1246,6 @@ export class ApplicationShell extends Widget {
1237
1246
  this.onDidChangeActiveWidgetEmitter.fire(args);
1238
1247
  }
1239
1248
 
1240
- /**
1241
- * Set the z-index of the given element and its ancestors to the value `z`.
1242
- */
1243
- private setZIndex(element: HTMLElement, z: string | null): void {
1244
- element.style.zIndex = z || '';
1245
- const parent = element.parentElement;
1246
- if (parent && parent !== this.node) {
1247
- this.setZIndex(parent, z);
1248
- }
1249
- }
1250
-
1251
1249
  /**
1252
1250
  * Track the given widget so it is considered in the `current` and `active` state of the shell.
1253
1251
  */
@@ -2118,11 +2116,75 @@ export class ApplicationShell extends Widget {
2118
2116
  toggleMaximized(widget: Widget | undefined = this.currentWidget): void {
2119
2117
  const area = widget && this.getAreaPanelFor(widget);
2120
2118
  if (area instanceof TheiaDockPanel && (area === this.mainPanel || area === this.bottomPanel)) {
2121
- area.toggleMaximized();
2119
+ this.doToggleMaximized(area);
2122
2120
  this.revealWidget(widget!.id);
2123
2121
  }
2124
2122
  }
2125
2123
 
2124
+ protected handleMenuBarVisibility(newValue: string): void {
2125
+ if (newValue === 'visible') {
2126
+ const topRect = this.topPanel.node.getBoundingClientRect();
2127
+ this.maximizedElement.style.top = `${topRect.bottom}px`;
2128
+ } else {
2129
+ this.maximizedElement.style.removeProperty('top');
2130
+ }
2131
+ }
2132
+
2133
+ protected readonly onDidToggleMaximizedEmitter = new Emitter<Widget>();
2134
+ readonly onDidToggleMaximized = this.onDidToggleMaximizedEmitter.event;
2135
+
2136
+ protected unmaximize: (() => void) | undefined;
2137
+ doToggleMaximized(area: TheiaDockPanel): void {
2138
+ if (this.unmaximize) {
2139
+ this.unmaximize();
2140
+ this.unmaximize = undefined;
2141
+ return;
2142
+ }
2143
+
2144
+ const removedListener = () => {
2145
+ if (!area.widgets().next().value) {
2146
+ this.doToggleMaximized(area);
2147
+ }
2148
+ };
2149
+
2150
+ const parent = area.parent as SplitPanel;
2151
+ const layout = area.parent?.layout as SplitLayout;
2152
+ const sizes = layout.relativeSizes().slice();
2153
+ const stretch = SplitPanel.getStretch(area);
2154
+ const index = parent.widgets.indexOf(area);
2155
+ parent.layout?.removeWidget(area);
2156
+
2157
+ // eslint-disable-next-line no-null/no-null
2158
+ this.maximizedElement.style.display = 'block';
2159
+ area.addClass(MAXIMIZED_CLASS);
2160
+ const topRect = this.topPanel.node.getBoundingClientRect();
2161
+ UnsafeWidgetUtilities.attach(area, this.maximizedElement);
2162
+ this.maximizedElement.style.top = `${topRect.bottom}px`;
2163
+ area.fit();
2164
+ const observer = new ResizeObserver(entries => {
2165
+ area.fit();
2166
+ });
2167
+ observer.observe(this.maximizedElement);
2168
+
2169
+ this.unmaximize = () => {
2170
+ observer.unobserve(this.maximizedElement);
2171
+ observer.disconnect();
2172
+ this.maximizedElement.style.display = 'none';
2173
+ area.removeClass(MAXIMIZED_CLASS);
2174
+ if (area.isAttached) {
2175
+ UnsafeWidgetUtilities.detach(area);
2176
+ }
2177
+ parent?.insertWidget(index, area);
2178
+ SplitPanel.setStretch(area, stretch);
2179
+ layout.setRelativeSizes(sizes);
2180
+ parent.fit();
2181
+ this.onDidToggleMaximizedEmitter.fire(area);
2182
+ area.widgetRemoved.disconnect(removedListener);
2183
+ };
2184
+
2185
+ area.widgetRemoved.connect(removedListener);
2186
+ this.onDidToggleMaximizedEmitter.fire(area);
2187
+ }
2126
2188
  }
2127
2189
 
2128
2190
  /**
@@ -21,3 +21,4 @@ export * from './sidebar-menu-widget';
21
21
  export * from './split-panels';
22
22
  export * from './tab-bars';
23
23
  export * from './view-contribution';
24
+ export * from './theia-split-panel';
@@ -33,7 +33,8 @@ export class SidebarBottomMenuWidget extends SidebarMenuWidget {
33
33
  x: button.left + button.width,
34
34
  y: button.top + button.height,
35
35
  },
36
- context: e.currentTarget
36
+ context: e.currentTarget,
37
+ contextKeyService: this.contextKeyService
37
38
  });
38
39
  }
39
40
 
@@ -18,9 +18,10 @@ import { injectable, inject } from 'inversify';
18
18
  import * as React from 'react';
19
19
  import { ReactWidget } from '../widgets';
20
20
  import { ContextMenuRenderer } from '../context-menu-renderer';
21
- import { MenuPath } from '../../common/menu';
21
+ import { CompoundMenuNode, MenuModelRegistry, MenuPath } from '../../common/menu';
22
22
  import { HoverService } from '../hover-service';
23
23
  import { Event, Disposable, Emitter, DisposableCollection } from '../../common';
24
+ import { ContextKeyService } from '../context-key-service';
24
25
 
25
26
  export const SidebarTopMenuWidgetFactory = Symbol('SidebarTopMenuWidgetFactory');
26
27
  export const SidebarBottomMenuWidgetFactory = Symbol('SidebarBottomMenuWidgetFactory');
@@ -90,9 +91,15 @@ export class SidebarMenuWidget extends ReactWidget {
90
91
  @inject(ContextMenuRenderer)
91
92
  protected readonly contextMenuRenderer: ContextMenuRenderer;
92
93
 
94
+ @inject(MenuModelRegistry)
95
+ protected readonly menuRegistry: MenuModelRegistry;
96
+
93
97
  @inject(HoverService)
94
98
  protected readonly hoverService: HoverService;
95
99
 
100
+ @inject(ContextKeyService)
101
+ protected readonly contextKeyService: ContextKeyService;
102
+
96
103
  constructor() {
97
104
  super();
98
105
  this.items = [];
@@ -145,14 +152,17 @@ export class SidebarMenuWidget extends ReactWidget {
145
152
  protected onClick(e: React.MouseEvent<HTMLElement, MouseEvent>, menuPath: MenuPath): void {
146
153
  this.preservingContext = true;
147
154
  const button = e.currentTarget.getBoundingClientRect();
155
+ const menu = this.menuRegistry.getMenuNode(menuPath) as CompoundMenuNode;
148
156
  this.contextMenuRenderer.render({
149
- menuPath,
157
+ menuPath: menuPath,
158
+ menu: menu,
150
159
  includeAnchorArg: false,
151
160
  anchor: {
152
161
  x: button.left + button.width,
153
162
  y: button.top,
154
163
  },
155
164
  context: e.currentTarget,
165
+ contextKeyService: this.contextKeyService,
156
166
  onHide: () => {
157
167
  this.preservingContext = false;
158
168
  if (this.preservedContext) {
@@ -0,0 +1,239 @@
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-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { Widget } from '@lumino/widgets';
18
+ import * as React from 'react';
19
+ import { CommandRegistry, Event } from '../../../common';
20
+ import { NAVIGATION, RenderedToolbarAction } from './tab-bar-toolbar-types';
21
+ import { TabBarToolbar, toAnchor } from './tab-bar-toolbar';
22
+ import { ACTION_ITEM, codicon } from '../../widgets';
23
+ import { ContextMenuRenderer } from '../../context-menu-renderer';
24
+ import { TabBarToolbarItem } from './tab-toolbar-item';
25
+ import { ContextKeyService, ContextMatcher } from '../../context-key-service';
26
+ import { CommandMenu, CompoundMenuNode, MenuModelRegistry, MenuNode, MenuPath, RenderedMenuNode } from '../../../common/menu';
27
+
28
+ export const TOOLBAR_WRAPPER_ID_SUFFIX = '-as-tabbar-toolbar-item';
29
+
30
+ abstract class AbstractToolbarMenuWrapper {
31
+
32
+ constructor(
33
+ protected readonly effectiveMenuPath: MenuPath,
34
+ protected readonly commandRegistry: CommandRegistry,
35
+ protected readonly menuRegistry: MenuModelRegistry,
36
+ protected readonly contextKeyService: ContextKeyService,
37
+ protected readonly contextMenuRenderer: ContextMenuRenderer) {
38
+ }
39
+
40
+ protected abstract menuPath?: MenuPath;
41
+ protected abstract menuNode: MenuNode;
42
+ protected abstract id: string;
43
+ protected abstract icon: string | undefined;
44
+ protected abstract tooltip: string | undefined;
45
+ protected abstract text: string | undefined;
46
+ protected abstract executeCommand(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
47
+
48
+ isEnabled(): boolean {
49
+ if (CommandMenu.is(this.menuNode)) {
50
+ return this.menuNode.isEnabled(this.effectiveMenuPath);
51
+ }
52
+ return true;
53
+ }
54
+ isToggled(): boolean {
55
+ if (CommandMenu.is(this.menuNode) && this.menuNode.isToggled) {
56
+ return !!this.menuNode.isToggled(this.effectiveMenuPath);
57
+ }
58
+ return false;
59
+ }
60
+ render(widget: Widget): React.ReactNode {
61
+ return this.renderMenuItem(widget);
62
+ }
63
+
64
+ toMenuNode?(): MenuNode {
65
+ return this.menuNode;
66
+ }
67
+
68
+ /**
69
+ * Presents the menu to popup on the `event` that is the clicking of
70
+ * a menu toolbar item.
71
+ *
72
+ * @param menuPath the path of the registered menu to show
73
+ * @param event the mouse event triggering the menu
74
+ */
75
+ showPopupMenu(widget: Widget | undefined, menuPath: MenuPath, event: React.MouseEvent, contextMatcher: ContextMatcher): void {
76
+ event.stopPropagation();
77
+ event.preventDefault();
78
+ const anchor = toAnchor(event);
79
+
80
+ this.contextMenuRenderer.render({
81
+ menuPath: menuPath,
82
+ menu: this.menuNode as CompoundMenuNode,
83
+ args: [widget],
84
+ anchor,
85
+ context: widget?.node || event.target as HTMLElement,
86
+ contextKeyService: contextMatcher,
87
+ });
88
+ }
89
+
90
+ /**
91
+ * Renders a toolbar item that is a menu, presenting it as a button with a little
92
+ * chevron decoration that pops up a floating menu when clicked.
93
+ *
94
+ * @param item a toolbar item that is a menu item
95
+ * @returns the rendered toolbar item
96
+ */
97
+ protected renderMenuItem(widget: Widget): React.ReactNode {
98
+ const icon = this.icon || 'ellipsis';
99
+ const contextMatcher: ContextMatcher = this.contextKeyService;
100
+ if (CompoundMenuNode.is(this.menuNode) && !this.menuNode.isEmpty(this.effectiveMenuPath, this.contextKeyService, widget.node)) {
101
+
102
+ return <div key={this.id} className={TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM + ' enabled menu'}>
103
+ <div className={codicon(icon, true)}
104
+ title={this.text}
105
+ onClick={e => this.executeCommand(e)}
106
+ />
107
+ <div className={ACTION_ITEM} onClick={event => this.showPopupMenu(widget, this.menuPath!, event, contextMatcher)} >
108
+ <div className={codicon('chevron-down') + ' chevron'} />
109
+ </div>
110
+ </div>;
111
+ } else {
112
+ return <div key={this.id} className={TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM + ' enabled menu'}>
113
+ <div className={codicon(icon, true)}
114
+ title={this.text}
115
+ onClick={e => this.executeCommand(e)}
116
+ />
117
+ </div>;
118
+ }
119
+ }
120
+ }
121
+
122
+ export class ToolbarMenuNodeWrapper extends AbstractToolbarMenuWrapper implements TabBarToolbarItem {
123
+ constructor(
124
+ effectiveMenuPath: MenuPath,
125
+ commandRegistry: CommandRegistry,
126
+ menuRegistry: MenuModelRegistry,
127
+ contextKeyService: ContextKeyService,
128
+ contextMenuRenderer: ContextMenuRenderer,
129
+ protected readonly menuNode: MenuNode & RenderedMenuNode,
130
+ readonly group: string | undefined,
131
+ readonly menuPath?: MenuPath) {
132
+ super(effectiveMenuPath, commandRegistry, menuRegistry, contextKeyService, contextMenuRenderer);
133
+ }
134
+
135
+ executeCommand(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void {
136
+ if (CommandMenu.is(this.menuNode)) {
137
+ this.menuNode.run(this.effectiveMenuPath);
138
+ }
139
+ }
140
+
141
+ isVisible(widget: Widget): boolean {
142
+ const menuNodeVisible = this.menuNode.isVisible(this.effectiveMenuPath, this.contextKeyService, widget.node);
143
+ if (CommandMenu.is(this.menuNode)) {
144
+ return menuNodeVisible;
145
+ } else if (CompoundMenuNode.is(this.menuNode)) {
146
+ return menuNodeVisible && !MenuModelRegistry.isEmpty(this.menuNode);
147
+ } else {
148
+ return menuNodeVisible;
149
+ }
150
+ }
151
+
152
+ get id(): string { return this.menuNode.id + TOOLBAR_WRAPPER_ID_SUFFIX; }
153
+ get icon(): string | undefined { return this.menuNode.icon; }
154
+ get tooltip(): string | undefined { return this.menuNode.label; }
155
+ get text(): string | undefined {
156
+ return (this.group === NAVIGATION || this.group === undefined) ? undefined : this.menuNode.label;
157
+ }
158
+ get onDidChange(): Event<void> | undefined {
159
+ return this.menuNode.onDidChange;
160
+ }
161
+ }
162
+
163
+ export class ToolbarSubmenuWrapper extends AbstractToolbarMenuWrapper implements TabBarToolbarItem {
164
+ constructor(
165
+ effectiveMenuPath: MenuPath,
166
+ commandRegistry: CommandRegistry,
167
+ menuRegistry: MenuModelRegistry,
168
+ contextKeyService: ContextKeyService,
169
+ contextMenuRenderer: ContextMenuRenderer,
170
+ protected readonly toolbarItem: RenderedToolbarAction
171
+ ) {
172
+ super(effectiveMenuPath, commandRegistry, menuRegistry, contextKeyService, contextMenuRenderer);
173
+ }
174
+
175
+ override isEnabled(widget?: Widget): boolean {
176
+ return this.toolbarItem.command ? this.commandRegistry.isEnabled(this.toolbarItem.command, widget) : !!this.toolbarItem.menuPath;
177
+ }
178
+
179
+ protected executeCommand(e: React.MouseEvent<HTMLElement>, widget?: Widget): void {
180
+ e.preventDefault();
181
+ e.stopPropagation();
182
+
183
+ if (!this.isEnabled(widget)) {
184
+ return;
185
+ }
186
+
187
+ if (this.toolbarItem.command) {
188
+ this.commandRegistry.executeCommand(this.toolbarItem.command, widget);
189
+ }
190
+ };
191
+
192
+ isVisible(widget: Widget): boolean {
193
+ const menuNode = this.menuNode;
194
+ if (this.toolbarItem.isVisible && !this.toolbarItem.isVisible(widget)) {
195
+ return false;
196
+ }
197
+ if (!menuNode.isVisible(this.effectiveMenuPath, this.contextKeyService, widget.node, widget)) {
198
+ return false;
199
+ }
200
+ if (this.toolbarItem.command) {
201
+ return true;
202
+ }
203
+ if (CompoundMenuNode.is(menuNode)) {
204
+ return !menuNode.isEmpty(this.effectiveMenuPath, this.contextKeyService, widget.node, widget);
205
+ }
206
+ return true;
207
+ }
208
+ group?: string | undefined;
209
+ priority?: number | undefined;
210
+
211
+ get id(): string { return this.toolbarItem.id; }
212
+ get icon(): string | undefined {
213
+ if (typeof this.toolbarItem.icon === 'function') {
214
+ return this.toolbarItem.icon();
215
+ }
216
+ if (this.toolbarItem.icon) {
217
+ return this.toolbarItem.icon;
218
+ }
219
+ if (this.toolbarItem.command) {
220
+ const command = this.commandRegistry.getCommand(this.toolbarItem.command);
221
+ return command?.iconClass;
222
+ }
223
+ return undefined;
224
+ }
225
+ get tooltip(): string | undefined { return this.toolbarItem.tooltip; }
226
+ get text(): string | undefined { return (this.toolbarItem.group === NAVIGATION || this.toolbarItem.group === undefined) ? undefined : this.toolbarItem.text; }
227
+ get onDidChange(): Event<void> | undefined {
228
+ return this.menuNode.onDidChange;
229
+ }
230
+
231
+ get menuPath(): MenuPath {
232
+ return this.toolbarItem.menuPath!;
233
+ }
234
+
235
+ get menuNode(): MenuNode {
236
+ return this.menuRegistry.getMenu(this.menuPath);
237
+ }
238
+ }
239
+