@theia/core 1.63.0-next.52 → 1.63.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 (92) hide show
  1. package/README.md +7 -7
  2. package/i18n/nls.cs.json +112 -5
  3. package/i18n/nls.de.json +112 -5
  4. package/i18n/nls.es.json +112 -5
  5. package/i18n/nls.fr.json +112 -5
  6. package/i18n/nls.hu.json +112 -5
  7. package/i18n/nls.it.json +112 -5
  8. package/i18n/nls.ja.json +112 -5
  9. package/i18n/nls.json +116 -9
  10. package/i18n/nls.ko.json +112 -5
  11. package/i18n/nls.pl.json +112 -5
  12. package/i18n/nls.pt-br.json +112 -5
  13. package/i18n/nls.ru.json +112 -5
  14. package/i18n/nls.tr.json +112 -5
  15. package/i18n/nls.zh-cn.json +112 -5
  16. package/i18n/nls.zh-tw.json +112 -5
  17. package/lib/browser/catalog.json +110 -23
  18. package/lib/browser/context-menu-renderer.d.ts.map +1 -1
  19. package/lib/browser/context-menu-renderer.js +4 -1
  20. package/lib/browser/context-menu-renderer.js.map +1 -1
  21. package/lib/browser/core-preferences.d.ts +1 -0
  22. package/lib/browser/core-preferences.d.ts.map +1 -1
  23. package/lib/browser/core-preferences.js +12 -0
  24. package/lib/browser/core-preferences.js.map +1 -1
  25. package/lib/browser/hover-service.d.ts +5 -0
  26. package/lib/browser/hover-service.d.ts.map +1 -1
  27. package/lib/browser/hover-service.js +12 -0
  28. package/lib/browser/hover-service.js.map +1 -1
  29. package/lib/browser/menu/browser-menu-plugin.d.ts.map +1 -1
  30. package/lib/browser/menu/browser-menu-plugin.js +4 -5
  31. package/lib/browser/menu/browser-menu-plugin.js.map +1 -1
  32. package/lib/browser/menu/menu.spec.js +2 -0
  33. package/lib/browser/menu/menu.spec.js.map +1 -1
  34. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  35. package/lib/browser/shell/application-shell.js +3 -2
  36. package/lib/browser/shell/application-shell.js.map +1 -1
  37. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts +3 -3
  38. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.d.ts.map +1 -1
  39. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js +3 -2
  40. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.js.map +1 -1
  41. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.d.ts.map +1 -1
  42. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js +11 -9
  43. package/lib/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.js.map +1 -1
  44. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts +1 -1
  45. package/lib/browser/shell/tab-bar-toolbar/tab-toolbar-item.d.ts.map +1 -1
  46. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  47. package/lib/browser/shell/tab-bars.js +21 -8
  48. package/lib/browser/shell/tab-bars.js.map +1 -1
  49. package/lib/browser/widgets/select-component.d.ts +2 -0
  50. package/lib/browser/widgets/select-component.d.ts.map +1 -1
  51. package/lib/browser/widgets/select-component.js +21 -7
  52. package/lib/browser/widgets/select-component.js.map +1 -1
  53. package/lib/common/index.d.ts +1 -0
  54. package/lib/common/index.d.ts.map +1 -1
  55. package/lib/common/index.js +1 -0
  56. package/lib/common/index.js.map +1 -1
  57. package/lib/common/menu/menu-model-registry.d.ts +2 -2
  58. package/lib/common/menu/menu-model-registry.d.ts.map +1 -1
  59. package/lib/common/menu/menu-model-registry.js +25 -32
  60. package/lib/common/menu/menu-model-registry.js.map +1 -1
  61. package/lib/common/menu/menu-types.d.ts +2 -2
  62. package/lib/common/menu/menu-types.d.ts.map +1 -1
  63. package/lib/common/menu/menu-types.js.map +1 -1
  64. package/lib/common/resource.d.ts +3 -3
  65. package/lib/common/resource.d.ts.map +1 -1
  66. package/lib/common/resource.js +4 -6
  67. package/lib/common/resource.js.map +1 -1
  68. package/lib/electron-browser/preload.d.ts.map +1 -1
  69. package/lib/electron-browser/preload.js +17 -0
  70. package/lib/electron-browser/preload.js.map +1 -1
  71. package/lib/electron-common/electron-api.d.ts +1 -0
  72. package/lib/electron-common/electron-api.d.ts.map +1 -1
  73. package/lib/electron-common/electron-api.js.map +1 -1
  74. package/package.json +6 -6
  75. package/src/browser/context-menu-renderer.ts +5 -2
  76. package/src/browser/core-preferences.ts +13 -0
  77. package/src/browser/hover-service.ts +13 -0
  78. package/src/browser/menu/browser-menu-plugin.ts +4 -5
  79. package/src/browser/menu/menu.spec.ts +3 -1
  80. package/src/browser/shell/application-shell.ts +3 -2
  81. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-menu-adapters.tsx +5 -5
  82. package/src/browser/shell/tab-bar-toolbar/tab-bar-toolbar-registry.ts +14 -11
  83. package/src/browser/shell/tab-bar-toolbar/tab-toolbar-item.tsx +1 -1
  84. package/src/browser/shell/tab-bars.ts +32 -15
  85. package/src/browser/style/tabs.css +13 -2
  86. package/src/browser/widgets/select-component.tsx +22 -6
  87. package/src/common/index.ts +1 -0
  88. package/src/common/menu/menu-model-registry.ts +27 -33
  89. package/src/common/menu/menu-types.ts +2 -2
  90. package/src/common/resource.ts +5 -7
  91. package/src/electron-browser/preload.ts +3 -1
  92. package/src/electron-common/electron-api.ts +2 -0
@@ -119,6 +119,15 @@ export class TabBarRenderer extends TabBar.Renderer {
119
119
  }
120
120
  }));
121
121
  }
122
+ if (this.corePreferences) {
123
+ this.toDispose.push(
124
+ this.corePreferences.onPreferenceChanged(event => {
125
+ if (event.preferenceName === 'window.tabCloseIconPlacement' && this._tabBar) {
126
+ this._tabBar.update();
127
+ }
128
+ })
129
+ );
130
+ }
122
131
  }
123
132
 
124
133
  dispose(): void {
@@ -160,22 +169,42 @@ export class TabBarRenderer extends TabBar.Renderer {
160
169
  * @returns {VirtualElement} The virtual element of the rendered tab.
161
170
  */
162
171
  override renderTab(data: SideBarRenderData, isInSidePanel?: boolean, isPartOfHiddenTabBar?: boolean): VirtualElement {
172
+ // Putting the close icon at the start is only pertinent to the horizontal orientation
173
+ const isHorizontal = this.tabBar?.orientation === 'horizontal';
174
+ const tabCloseIconStart = isHorizontal && this.corePreferences?.['window.tabCloseIconPlacement'] === 'start';
175
+
163
176
  const title = data.title;
164
177
  const id = this.createTabId(title, isPartOfHiddenTabBar);
165
178
  const key = this.createTabKey(data);
166
179
  const style = this.createTabStyle(data);
167
- const className = this.createTabClass(data);
180
+ const className = `${this.createTabClass(data)}${tabCloseIconStart ? ' closeIcon-start' : ''}`;
168
181
  const dataset = this.createTabDataset(data);
169
182
  const closeIconTitle = data.title.className.includes(PINNED_CLASS)
170
183
  ? nls.localizeByDefault('Unpin')
171
184
  : nls.localizeByDefault('Close');
172
185
 
173
- const hover = this.tabBar && (this.tabBar.orientation === 'horizontal' && this.corePreferences?.['window.tabbar.enhancedPreview'] === 'classic')
186
+ const hover = isHorizontal && this.corePreferences?.['window.tabbar.enhancedPreview'] === 'classic'
174
187
  ? { title: title.caption }
175
188
  : {
176
189
  onmouseenter: this.handleMouseEnterEvent
177
190
  };
178
191
 
192
+ const tabLabel = h.div(
193
+ { className: 'theia-tab-icon-label' },
194
+ this.renderIcon(data, isInSidePanel),
195
+ this.renderLabel(data, isInSidePanel),
196
+ this.renderTailDecorations(data, isInSidePanel),
197
+ this.renderBadge(data, isInSidePanel),
198
+ this.renderLock(data, isInSidePanel)
199
+ );
200
+ const tabCloseIcon = h.div({
201
+ className: 'lm-TabBar-tabCloseIcon action-label',
202
+ title: closeIconTitle,
203
+ onclick: this.handleCloseClickEvent,
204
+ });
205
+
206
+ const tabContents = tabCloseIconStart ? [tabCloseIcon, tabLabel] : [tabLabel, tabCloseIcon];
207
+
179
208
  return h.li(
180
209
  {
181
210
  ...hover,
@@ -187,19 +216,7 @@ export class TabBarRenderer extends TabBar.Renderer {
187
216
  e.preventDefault();
188
217
  }
189
218
  },
190
- h.div(
191
- { className: 'theia-tab-icon-label' },
192
- this.renderIcon(data, isInSidePanel),
193
- this.renderLabel(data, isInSidePanel),
194
- this.renderTailDecorations(data, isInSidePanel),
195
- this.renderBadge(data, isInSidePanel),
196
- this.renderLock(data, isInSidePanel)
197
- ),
198
- h.div({
199
- className: 'lm-TabBar-tabCloseIcon action-label',
200
- title: closeIconTitle,
201
- onclick: this.handleCloseClickEvent
202
- })
219
+ ...tabContents
203
220
  );
204
221
  }
205
222
 
@@ -237,6 +237,12 @@
237
237
  -ms-user-select: none;
238
238
  }
239
239
 
240
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable.closeIcon-start > .lm-TabBar-tabCloseIcon,
241
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.theia-mod-pinned.closeIcon-start > .lm-TabBar-tabCloseIcon {
242
+ margin-left: inherit;
243
+ margin-right: 4px;
244
+ }
245
+
240
246
  .lm-TabBar.theia-app-centers.dynamic-tabs .lm-TabBar-tab.lm-mod-closable>.lm-TabBar-tabCloseIcon,
241
247
  .lm-TabBar.theia-app-centers.dynamic-tabs .lm-TabBar-tab.theia-mod-pinned>.lm-TabBar-tabCloseIcon {
242
248
  /* hide close icon for dynamic tabs strategy*/
@@ -254,11 +260,16 @@
254
260
  background-color: rgba(50%, 50%, 50%, 0.2);
255
261
  }
256
262
 
257
- .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable,
258
- .lm-TabBar.theia-app-centers .lm-TabBar-tab.theia-mod-pinned {
263
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable:not(.closeIcon-start),
264
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.theia-mod-pinned:not(.closeIcon-start) {
259
265
  padding-right: 4px;
260
266
  }
261
267
 
268
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable.closeIcon-start,
269
+ .lm-TabBar.theia-app-centers .lm-TabBar-tab.theia-mod-pinned.closeIcon-start {
270
+ padding-left: 4px;
271
+ }
272
+
262
273
  .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable:not(.theia-mod-dirty):hover>.lm-TabBar-tabCloseIcon:before,
263
274
  .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable:not(.theia-mod-dirty).lm-TabBar-tab.lm-mod-current>.lm-TabBar-tabCloseIcon:before,
264
275
  .lm-TabBar.theia-app-centers .lm-TabBar-tab.lm-mod-closable.theia-mod-dirty>.lm-TabBar-tabCloseIcon:hover:before {
@@ -61,12 +61,7 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
61
61
 
62
62
  constructor(props: SelectComponentProps) {
63
63
  super(props);
64
- let selected = 0;
65
- if (typeof props.defaultValue === 'number') {
66
- selected = props.defaultValue;
67
- } else if (typeof props.defaultValue === 'string') {
68
- selected = Math.max(props.options.findIndex(e => e.value === props.defaultValue), 0);
69
- }
64
+ const selected = this.getInitialSelectedIndex(props);
70
65
  this.state = {
71
66
  selected,
72
67
  original: selected,
@@ -83,6 +78,27 @@ export class SelectComponent extends React.Component<SelectComponentProps, Selec
83
78
  this.dropdownElement = list;
84
79
  }
85
80
 
81
+ protected getInitialSelectedIndex(props: SelectComponentProps): number {
82
+ let selected = 0;
83
+ if (typeof props.defaultValue === 'number') {
84
+ selected = props.defaultValue;
85
+ } else if (typeof props.defaultValue === 'string') {
86
+ selected = Math.max(props.options.findIndex(e => e.value === props.defaultValue), 0);
87
+ }
88
+ return selected;
89
+ }
90
+
91
+ override componentDidUpdate(prevProps: SelectComponentProps): void {
92
+ if (prevProps.defaultValue !== this.props.defaultValue || prevProps.options !== this.props.options) {
93
+ const selected = this.getInitialSelectedIndex(this.props);
94
+ this.setState({
95
+ selected,
96
+ original: selected,
97
+ hover: selected
98
+ });
99
+ }
100
+ }
101
+
86
102
  get options(): readonly SelectOption[] {
87
103
  return this.props.options;
88
104
  }
@@ -22,6 +22,7 @@ export * from './contribution-filter';
22
22
  export * from './contribution-provider';
23
23
  export * from './disposable';
24
24
  export * from './event';
25
+ export * from './listener';
25
26
  export * from './logger';
26
27
  export * from './lsp-types';
27
28
  export * from './menu';
@@ -132,21 +132,15 @@ export class MenuModelRegistry {
132
132
  */
133
133
  registerCommandMenu(menuPath: MenuPath, item: CommandMenu): Disposable {
134
134
  const parent = this.root.getOrCreate(menuPath, 0, menuPath.length);
135
- const existing = parent.children.find(node => node.id === menuPath[menuPath.length - 1]);
136
- if (existing) {
137
- throw new Error(`A menu node with path ${JSON.stringify(menuPath)} already exists`);
138
- } else {
139
- parent.addNode(item);
140
- return Disposable.create(() => {
141
- parent.removeNode(item);
142
- this.fireChangeEvent({
143
- kind: ChangeKind.REMOVED,
144
- path: menuPath.slice(0, menuPath.length - 1),
145
- affectedChildId: item.id
146
- });
135
+ parent.addNode(item);
136
+ return Disposable.create(() => {
137
+ parent.removeNode(item);
138
+ this.fireChangeEvent({
139
+ kind: ChangeKind.REMOVED,
140
+ path: menuPath.slice(0, menuPath.length - 1),
141
+ affectedChildId: item.id
147
142
  });
148
- }
149
-
143
+ });
150
144
  }
151
145
 
152
146
  /**
@@ -156,21 +150,16 @@ export class MenuModelRegistry {
156
150
  */
157
151
  registerMenuAction(menuPath: MenuPath, item: MenuAction): Disposable {
158
152
  const parent = this.root.getOrCreate(menuPath, 0, menuPath.length);
159
- const existing = parent.children.find(node => node.id === item.commandId);
160
- if (existing) {
161
- throw new Error(`A menu node with id ${item.commandId} in path ${JSON.stringify(menuPath)} already exists`);
162
- } else {
163
- const node = this.menuNodeFactory.createCommandMenu(item);
164
- parent.addNode(node);
165
- return Disposable.create(() => {
166
- parent.removeNode(node);
167
- this.fireChangeEvent({
168
- kind: ChangeKind.REMOVED,
169
- path: menuPath.slice(0, menuPath.length - 1),
170
- affectedChildId: node.id
171
- });
153
+ const node = this.menuNodeFactory.createCommandMenu(item);
154
+ parent.addNode(node);
155
+ return Disposable.create(() => {
156
+ parent.removeNode(node);
157
+ this.fireChangeEvent({
158
+ kind: ChangeKind.REMOVED,
159
+ path: menuPath.slice(0, menuPath.length - 1),
160
+ affectedChildId: node.id
172
161
  });
173
- }
162
+ });
174
163
 
175
164
  }
176
165
 
@@ -311,13 +300,15 @@ export class MenuModelRegistry {
311
300
  }
312
301
  }
313
302
 
314
- protected findInNode(root: CompoundMenuNode, menuPath: MenuPath, pathIndex: number): MenuNode | undefined {
303
+ protected findInNode(root: MenuNode, menuPath: MenuPath, pathIndex: number): MenuNode | undefined {
315
304
  if (pathIndex === menuPath.length) {
316
305
  return root;
317
306
  }
318
- const child = root.children.find(c => c.id === menuPath[pathIndex]);
319
- if (CompoundMenuNode.is(child)) {
320
- return this.findInNode(child, menuPath, pathIndex + 1);
307
+ if (CompoundMenuNode.is(root)) {
308
+ const child = root.children.find(c => c.id === menuPath[pathIndex]);
309
+ if (child) {
310
+ return this.findInNode(child, menuPath, pathIndex + 1);
311
+ }
321
312
  }
322
313
  return undefined;
323
314
  }
@@ -326,8 +317,11 @@ export class MenuModelRegistry {
326
317
  return this.findInNode(this.root, menuPath, 0);
327
318
  }
328
319
 
329
- getMenu(menuPath: MenuPath): CompoundMenuNode {
320
+ getMenu(menuPath: MenuPath): CompoundMenuNode | undefined {
330
321
  const node = this.getMenuNode(menuPath);
322
+ if (!node) {
323
+ return undefined;
324
+ }
331
325
  if (!CompoundMenuNode.is(node)) {
332
326
  throw new Error(`not a compound menu node: ${JSON.stringify(menuPath)}`);
333
327
  }
@@ -97,7 +97,7 @@ export interface RenderedMenuNode extends MenuNode {
97
97
  }
98
98
 
99
99
  export namespace RenderedMenuNode {
100
- export function is(node: object): node is RenderedMenuNode {
100
+ export function is(node: unknown): node is RenderedMenuNode {
101
101
  return isObject<RenderedMenuNode>(node) && typeof node.label === 'string';
102
102
  }
103
103
  }
@@ -105,7 +105,7 @@ export namespace RenderedMenuNode {
105
105
  export type CommandMenu = MenuNode & RenderedMenuNode & Action;
106
106
 
107
107
  export namespace CommandMenu {
108
- export function is(node: MenuNode): node is CommandMenu {
108
+ export function is(node: MenuNode | undefined): node is CommandMenu {
109
109
  return RenderedMenuNode.is(node) && Action.is(node);
110
110
  }
111
111
  }
@@ -367,11 +367,11 @@ export class UntitledResourceResolver implements ResourceResolver {
367
367
  }
368
368
  }
369
369
 
370
- async createUntitledResource(content?: string, extension?: string, uri?: URI): Promise<UntitledResource> {
370
+ async createUntitledResource(content?: string, extension?: string, uri?: URI, encoding?: string): Promise<UntitledResource> {
371
371
  if (!uri) {
372
372
  uri = this.createUntitledURI(extension);
373
373
  }
374
- return new UntitledResource(this.resources, uri, content);
374
+ return new UntitledResource(this.resources, uri, content, encoding);
375
375
  }
376
376
 
377
377
  createUntitledURI(extension?: string, parent?: URI): URI {
@@ -394,13 +394,15 @@ export class UntitledResource implements Resource {
394
394
  protected readonly onDidChangeContentsEmitter = new Emitter<void>();
395
395
  readonly initiallyDirty: boolean;
396
396
  readonly autosaveable = false;
397
+ readonly encoding: string | undefined;
397
398
  get onDidChangeContents(): Event<void> {
398
399
  return this.onDidChangeContentsEmitter.event;
399
400
  }
400
401
 
401
- constructor(private resources: Map<string, UntitledResource>, public uri: URI, private content?: string) {
402
+ constructor(private resources: Map<string, UntitledResource>, public uri: URI, private content?: string, encoding?: string) {
402
403
  this.initiallyDirty = (content !== undefined && content.length > 0);
403
404
  this.resources.set(this.uri.toString(), this);
405
+ this.encoding = encoding;
404
406
  }
405
407
 
406
408
  dispose(): void {
@@ -429,10 +431,6 @@ export class UntitledResource implements Resource {
429
431
  get version(): ResourceVersion | undefined {
430
432
  return undefined;
431
433
  }
432
-
433
- get encoding(): string | undefined {
434
- return undefined;
435
- }
436
434
  }
437
435
 
438
436
  /**
@@ -13,7 +13,7 @@
13
13
  //
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  //
16
- import { IpcRendererEvent } from '@theia/electron/shared/electron';
16
+ import { IpcRendererEvent, webUtils } from '@theia/electron/shared/electron';
17
17
  import { Disposable } from '../common/disposable';
18
18
  import { StopReason } from '../common/frontend-application-state';
19
19
  import { NativeKeyboardLayout } from '../common/keyboard/keyboard-layout-provider';
@@ -90,6 +90,8 @@ const api: TheiaCoreAPI = {
90
90
  showItemInFolder: fsPath => {
91
91
  ipcRenderer.send(CHANNEL_SHOW_ITEM_IN_FOLDER, fsPath);
92
92
  },
93
+
94
+ getPathForFile: (file: File) => webUtils.getPathForFile(file),
93
95
  openWithSystemApp: location => {
94
96
  ipcRenderer.send(CHANNEL_OPEN_WITH_SYSTEM_APP, location);
95
97
  },
@@ -58,6 +58,8 @@ export interface TheiaCoreAPI {
58
58
 
59
59
  showItemInFolder(fsPath: string): void;
60
60
 
61
+ getPathForFile(file: File): string;
62
+
61
63
  /**
62
64
  * @param location The location to open with the system app. This can be a file path or a URL.
63
65
  */