@theia/plugin-ext 1.22.0-next.2 → 1.22.0-next.23

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 (66) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +3 -3
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/main/browser/commands.d.ts.map +1 -1
  4. package/lib/main/browser/commands.js +2 -1
  5. package/lib/main/browser/commands.js.map +1 -1
  6. package/lib/main/browser/comments/comments-context-key-service.js +1 -1
  7. package/lib/main/browser/comments/comments-context-key-service.js.map +1 -1
  8. package/lib/main/browser/comments/comments-contribution.js +1 -1
  9. package/lib/main/browser/comments/comments-contribution.js.map +1 -1
  10. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts +3 -3
  11. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
  12. package/lib/main/browser/custom-editors/custom-editor-opener.js +1 -1
  13. package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
  14. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +3 -3
  15. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  16. package/lib/main/browser/custom-editors/custom-editors-main.js +34 -6
  17. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  18. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts +3 -3
  19. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts.map +1 -1
  20. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js +3 -3
  21. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js.map +1 -1
  22. package/lib/main/browser/dialogs/modal-notification.d.ts.map +1 -1
  23. package/lib/main/browser/dialogs/modal-notification.js +2 -1
  24. package/lib/main/browser/dialogs/modal-notification.js.map +1 -1
  25. package/lib/main/browser/dialogs-main.js +8 -8
  26. package/lib/main/browser/dialogs-main.js.map +1 -1
  27. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  28. package/lib/main/browser/menus/menus-contribution-handler.js +4 -6
  29. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  30. package/lib/main/browser/view/plugin-view-registry.js +1 -1
  31. package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
  32. package/lib/main/browser/view/plugin-view-widget.d.ts +5 -3
  33. package/lib/main/browser/view/plugin-view-widget.d.ts.map +1 -1
  34. package/lib/main/browser/view/plugin-view-widget.js +12 -4
  35. package/lib/main/browser/view/plugin-view-widget.js.map +1 -1
  36. package/lib/main/browser/view/tree-view-widget.d.ts +1 -2
  37. package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
  38. package/lib/main/browser/view/tree-view-widget.js +4 -5
  39. package/lib/main/browser/view/tree-view-widget.js.map +1 -1
  40. package/lib/main/browser/view/view-context-key-service.d.ts +0 -4
  41. package/lib/main/browser/view/view-context-key-service.d.ts.map +1 -1
  42. package/lib/main/browser/view/view-context-key-service.js +1 -14
  43. package/lib/main/browser/view/view-context-key-service.js.map +1 -1
  44. package/lib/plugin/custom-editors.d.ts +2 -1
  45. package/lib/plugin/custom-editors.d.ts.map +1 -1
  46. package/lib/plugin/custom-editors.js +2 -4
  47. package/lib/plugin/custom-editors.js.map +1 -1
  48. package/lib/plugin/types-impl.js +1 -1
  49. package/lib/plugin/types-impl.js.map +1 -1
  50. package/lib/plugin/types-impl.spec.js +33 -0
  51. package/lib/plugin/types-impl.spec.js.map +1 -1
  52. package/package.json +23 -23
  53. package/src/common/plugin-api-rpc.ts +3 -3
  54. package/src/main/browser/commands.ts +2 -1
  55. package/src/main/browser/custom-editors/custom-editor-opener.tsx +4 -4
  56. package/src/main/browser/custom-editors/custom-editors-main.ts +41 -8
  57. package/src/main/browser/custom-editors/plugin-custom-editor-registry.ts +6 -6
  58. package/src/main/browser/dialogs/modal-notification.ts +2 -1
  59. package/src/main/browser/dialogs-main.ts +7 -7
  60. package/src/main/browser/menus/menus-contribution-handler.ts +3 -7
  61. package/src/main/browser/view/plugin-view-widget.ts +14 -4
  62. package/src/main/browser/view/tree-view-widget.tsx +3 -4
  63. package/src/main/browser/view/view-context-key-service.ts +0 -14
  64. package/src/plugin/custom-editors.ts +3 -4
  65. package/src/plugin/types-impl.spec.ts +37 -1
  66. package/src/plugin/types-impl.ts +1 -1
@@ -23,14 +23,14 @@ import { CommandRegistry, Emitter, MenuModelRegistry } from '@theia/core';
23
23
  import { SelectionService } from '@theia/core/lib/common';
24
24
  import { UriAwareCommandHandler } from '@theia/core/lib/common/uri-command-handler';
25
25
  import { NavigatorContextMenu } from '@theia/navigator/lib//browser/navigator-contribution';
26
- import { ApplicationShell, DefaultOpenerService, WidgetManager } from '@theia/core/lib/browser';
26
+ import { ApplicationShell, DefaultOpenerService, WidgetManager, WidgetOpenerOptions } from '@theia/core/lib/browser';
27
27
  import { CustomEditorWidget } from './custom-editor-widget';
28
28
 
29
29
  @injectable()
30
30
  export class PluginCustomEditorRegistry {
31
31
  private readonly editors = new Map<string, CustomEditor>();
32
32
  private readonly pendingEditors = new Set<CustomEditorWidget>();
33
- private readonly resolvers = new Map<string, (widget: CustomEditorWidget) => void>();
33
+ private readonly resolvers = new Map<string, (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => void>();
34
34
 
35
35
  private readonly onWillOpenCustomEditorEmitter = new Emitter<string>();
36
36
  readonly onWillOpenCustomEditor = this.onWillOpenCustomEditorEmitter.event;
@@ -109,22 +109,22 @@ export class PluginCustomEditorRegistry {
109
109
  )
110
110
  );
111
111
  toDispose.push(
112
- editorOpenHandler.onDidOpenCustomEditor(widget => this.resolveWidget(widget))
112
+ editorOpenHandler.onDidOpenCustomEditor(event => this.resolveWidget(event[0], event[1]))
113
113
  );
114
114
  return toDispose;
115
115
  }
116
116
 
117
- resolveWidget = (widget: CustomEditorWidget) => {
117
+ resolveWidget = (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => {
118
118
  const resolver = this.resolvers.get(widget.viewType);
119
119
  if (resolver) {
120
- resolver(widget);
120
+ resolver(widget, options);
121
121
  } else {
122
122
  this.pendingEditors.add(widget);
123
123
  this.onWillOpenCustomEditorEmitter.fire(widget.viewType);
124
124
  }
125
125
  };
126
126
 
127
- registerResolver(viewType: string, resolver: (widget: CustomEditorWidget) => void): Disposable {
127
+ registerResolver(viewType: string, resolver: (widget: CustomEditorWidget, options?: WidgetOpenerOptions) => void): Disposable {
128
128
  if (this.resolvers.has(viewType)) {
129
129
  throw new Error(`Resolver for ${viewType} already registered`);
130
130
  }
@@ -20,6 +20,7 @@ import { AbstractDialog } from '@theia/core/lib/browser/dialogs';
20
20
  import '../../../../src/main/browser/dialogs/style/modal-notification.css';
21
21
  import { MainMessageItem, MainMessageOptions } from '../../../common/plugin-api-rpc';
22
22
  import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
23
+ import { nls } from '@theia/core/lib/common/nls';
23
24
 
24
25
  export enum MessageType {
25
26
  Error = 'error',
@@ -91,7 +92,7 @@ export class ModalNotification extends AbstractDialog<string | undefined> {
91
92
  if (actions.length <= 0) {
92
93
  this.appendAcceptButton();
93
94
  } else if (!actions.some(action => action.isCloseAffordance === true)) {
94
- this.appendCloseButton('Close');
95
+ this.appendCloseButton(nls.localizeByDefault('Close'));
95
96
  }
96
97
 
97
98
  return messageNode;
@@ -52,14 +52,14 @@ export class DialogsMainImpl implements DialogsMain {
52
52
  } catch {
53
53
  rootStat = undefined;
54
54
  }
55
- }
56
55
 
57
- // Try to use as root the parent folder of existing file URI/non existing URI
58
- if (rootStat && !rootStat.isDirectory || !rootStat) {
59
- try {
60
- rootStat = await this.fileService.resolve(new URI(defaultUri).parent);
61
- } catch {
62
- rootStat = undefined;
56
+ // Try to use as root the parent folder of existing file URI/non existing URI
57
+ if (rootStat && !rootStat.isDirectory || !rootStat) {
58
+ try {
59
+ rootStat = await this.fileService.resolve(new URI(defaultUri).parent);
60
+ } catch {
61
+ rootStat = undefined;
62
+ }
63
63
  }
64
64
  }
65
65
 
@@ -242,14 +242,10 @@ export class MenusContributionPointHandler {
242
242
  }
243
243
 
244
244
  protected registerViewTitleAction(location: string, action: Menu): Disposable {
245
- return this.registerTitleAction(location, { ...action, when: undefined }, {
245
+ return this.registerTitleAction(location, action, {
246
246
  execute: widget => widget instanceof PluginViewWidget && this.commands.executeCommand(action.command!),
247
- isEnabled: widget => widget instanceof PluginViewWidget &&
248
- this.viewContextKeys.with({ view: widget.options.viewId }, () =>
249
- this.commands.isEnabled(action.command!) && this.viewContextKeys.match(action.when)),
250
- isVisible: widget => widget instanceof PluginViewWidget &&
251
- this.viewContextKeys.with({ view: widget.options.viewId }, () =>
252
- this.commands.isVisible(action.command!) && this.viewContextKeys.match(action.when))
247
+ isEnabled: widget => widget instanceof PluginViewWidget && this.commands.isEnabled(action.command!),
248
+ isVisible: widget => widget instanceof PluginViewWidget && this.commands.isVisible(action.command!),
253
249
  });
254
250
  }
255
251
 
@@ -18,12 +18,12 @@ import { injectable, inject, postConstruct } from '@theia/core/shared/inversify'
18
18
  import { Panel, Widget } from '@theia/core/shared/@phosphor/widgets';
19
19
  import { MenuModelRegistry } from '@theia/core/lib/common/menu';
20
20
  import { CommandRegistry } from '@theia/core/lib/common/command';
21
- import { ViewContextKeyService } from './view-context-key-service';
22
21
  import { StatefulWidget } from '@theia/core/lib/browser/shell/shell-layout-restorer';
23
22
  import { Message } from '@theia/core/shared/@phosphor/messaging';
24
23
  import { TreeViewWidget } from './tree-view-widget';
25
24
  import { DescriptionWidget } from '@theia/core/lib/browser/view-container';
26
- import { Emitter } from '@theia/core/lib/common';
25
+ import { DisposableCollection, Emitter } from '@theia/core/lib/common';
26
+ import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
27
27
 
28
28
  @injectable()
29
29
  export class PluginViewWidgetIdentifier {
@@ -34,14 +34,16 @@ export class PluginViewWidgetIdentifier {
34
34
  @injectable()
35
35
  export class PluginViewWidget extends Panel implements StatefulWidget, DescriptionWidget {
36
36
 
37
+ protected readonly toDispose = new DisposableCollection();
38
+
37
39
  @inject(MenuModelRegistry)
38
40
  protected readonly menus: MenuModelRegistry;
39
41
 
40
42
  @inject(CommandRegistry)
41
43
  protected readonly commands: CommandRegistry;
42
44
 
43
- @inject(ViewContextKeyService)
44
- protected readonly contextKeys: ViewContextKeyService;
45
+ @inject(ContextKeyService)
46
+ protected readonly contextKeyService: ContextKeyService;
45
47
 
46
48
  @inject(PluginViewWidgetIdentifier)
47
49
  readonly options: PluginViewWidgetIdentifier;
@@ -59,6 +61,9 @@ export class PluginViewWidget extends Panel implements StatefulWidget, Descripti
59
61
  @postConstruct()
60
62
  protected init(): void {
61
63
  this.id = this.options.id;
64
+ const localContext = this.contextKeyService.createScoped(this.node);
65
+ localContext.setContext('view', this.options.viewId);
66
+ this.toDispose.push(localContext);
62
67
  }
63
68
 
64
69
  protected onActivateRequest(msg: Message): void {
@@ -148,6 +153,11 @@ export class PluginViewWidget extends Panel implements StatefulWidget, Descripti
148
153
  super.insertWidget(index, widget);
149
154
  this.updateWidgetMessage();
150
155
  }
156
+
157
+ dispose(): void {
158
+ this.toDispose.dispose();
159
+ super.dispose();
160
+ }
151
161
  }
152
162
  export namespace PluginViewWidget {
153
163
  export interface State {
@@ -36,7 +36,6 @@ import {
36
36
  import { MenuPath, MenuModelRegistry, ActionMenuNode } from '@theia/core/lib/common/menu';
37
37
  import * as React from '@theia/core/shared/react';
38
38
  import { PluginSharedStyle } from '../plugin-shared-style';
39
- import { ViewContextKeyService } from './view-context-key-service';
40
39
  import { ACTION_ITEM, Widget } from '@theia/core/lib/browser/widgets/widget';
41
40
  import { Emitter, Event } from '@theia/core/lib/common/event';
42
41
  import { MessageService } from '@theia/core/lib/common/message-service';
@@ -236,8 +235,8 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
236
235
  @inject(MenuModelRegistry)
237
236
  protected readonly menus: MenuModelRegistry;
238
237
 
239
- @inject(ViewContextKeyService)
240
- protected readonly contextKeys: ViewContextKeyService;
238
+ @inject(ContextKeyService)
239
+ protected readonly contextKeys: ContextKeyService;
241
240
 
242
241
  @inject(TreeViewWidgetIdentifier)
243
242
  readonly identifier: TreeViewWidgetIdentifier;
@@ -343,7 +342,7 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
343
342
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
344
343
  protected renderInlineCommand(node: ActionMenuNode, index: number, arg: any): React.ReactNode {
345
344
  const { icon } = node;
346
- if (!icon || !this.commands.isVisible(node.action.commandId, arg) || !this.contextKeys.match(node.action.when)) {
345
+ if (!icon || !this.commands.isVisible(node.action.commandId, arg) || !node.action.when || !this.contextKeys.match(node.action.when)) {
347
346
  return false;
348
347
  }
349
348
  const className = [TREE_NODE_SEGMENT_CLASS, TREE_NODE_TAIL_CLASS, icon, ACTION_ITEM, 'theia-tree-view-inline-action'].join(' ');
@@ -74,18 +74,4 @@ export class ViewContextKeyService {
74
74
  match(expression: string | undefined): boolean {
75
75
  return !expression || this.contextKeyService.match(expression);
76
76
  }
77
-
78
- with<T>(input: { view?: string, viewItem?: string }, cb: () => T): T {
79
- const view = this.view.get();
80
- const viewItem = this.viewItem.get();
81
- this.view.set(input.view);
82
- this.viewItem.set(input.viewItem);
83
- try {
84
- return cb();
85
- } finally {
86
- this.view.set(view);
87
- this.viewItem.set(viewItem);
88
- }
89
- }
90
-
91
77
  }
@@ -29,7 +29,7 @@ import { WebviewImpl, WebviewsExtImpl } from './webviews';
29
29
  import { CancellationToken, CancellationTokenSource } from '@theia/core/lib/common/cancellation';
30
30
  import { DisposableCollection } from '@theia/core/lib/common/disposable';
31
31
  import { WorkspaceExtImpl } from './workspace';
32
- import * as Converters from './type-converters';
32
+ import { WidgetOpenerOptions } from '@theia/core/lib/browser';
33
33
 
34
34
  export class CustomEditorsExtImpl implements CustomEditorsExt {
35
35
  private readonly proxy: CustomEditorsMain;
@@ -121,7 +121,7 @@ export class CustomEditorsExtImpl implements CustomEditorsExt {
121
121
  handler: string,
122
122
  viewType: string,
123
123
  title: string,
124
- position: number,
124
+ widgetOpenerOptions: WidgetOpenerOptions | undefined,
125
125
  options: theia.WebviewPanelOptions & theia.WebviewOptions,
126
126
  cancellation: CancellationToken
127
127
  ): Promise<void> {
@@ -129,10 +129,9 @@ export class CustomEditorsExtImpl implements CustomEditorsExt {
129
129
  if (!entry) {
130
130
  throw new Error(`No provider found for '${viewType}'`);
131
131
  }
132
- const viewColumn = Converters.toViewColumn(position);
133
132
  const panel = this.webviewExt.createWebviewPanel(viewType, title, {}, options, entry.plugin, handler);
134
133
  const webviewOptions = WebviewImpl.toWebviewOptions(options, this.workspace, entry.plugin);
135
- await this.proxy.$createCustomEditorPanel(handler, title, viewColumn, webviewOptions);
134
+ await this.proxy.$createCustomEditorPanel(handler, title, widgetOpenerOptions, webviewOptions);
136
135
 
137
136
  const revivedResource = URI.revive(resource);
138
137
 
@@ -14,13 +14,14 @@
14
14
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
15
  ********************************************************************************/
16
16
 
17
+ import { isWindows } from '@theia/core';
17
18
  import * as assert from 'assert';
18
19
  import * as types from './types-impl';
19
20
 
20
21
  describe('API Type Implementations:', () => {
21
22
 
22
23
  describe('URI:', () => {
23
- it('should convert to string', () => {
24
+ it('should convert to string', () => {
24
25
  const uriString = 'scheme://authority.com/foo/bar/zoz?query#fragment';
25
26
  const uri = types.URI.parse(uriString);
26
27
  // when
@@ -29,5 +30,40 @@ describe('API Type Implementations:', () => {
29
30
  // then
30
31
  assert.strictEqual(result, uriString);
31
32
  });
33
+
34
+ // Issue: #10370
35
+ it('should returns correct path while using joinPath()', () => {
36
+ if (isWindows) {
37
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\foo\\bar'), '/file.js').toString(), 'file:///c%3A/foo/bar/file.js');
38
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\foo\\bar\\'), 'file.js').toString(), 'file:///c%3A/foo/bar/file.js');
39
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\foo\\bar\\'), '/file.js').toString(), 'file:///c%3A/foo/bar/file.js');
40
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\'), '/file.js').toString(), 'file:///c%3A/file.js');
41
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\'), 'bar/file.js').toString(), 'file:///c%3A/bar/file.js');
42
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\foo'), './file.js').toString(), 'file:///c%3A/foo/file.js');
43
+ assert.strictEqual(types.URI.joinPath(types.URI.file('c:\\foo'), '/./file.js').toString(), 'file:///c%3A/foo/file.js');
44
+ assert.strictEqual(types.URI.joinPath(types.URI.file('C:\\foo'), '../file.js').toString(), 'file:///c%3A/file.js');
45
+ assert.strictEqual(types.URI.joinPath(types.URI.file('C:\\foo\\.'), '../file.js').toString(), 'file:///c%3A/file.js');
46
+ } else {
47
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar'), '/file.js').toString(), 'file:///foo/bar/file.js');
48
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar'), 'file.js').toString(), 'file:///foo/bar/file.js');
49
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar/'), '/file.js').toString(), 'file:///foo/bar/file.js');
50
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/'), '/file.js').toString(), 'file:///file.js');
51
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar'), './file.js').toString(), 'file:///foo/bar/file.js');
52
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar'), '/./file.js').toString(), 'file:///foo/bar/file.js');
53
+ assert.strictEqual(types.URI.joinPath(types.URI.file('/foo/bar'), '../file.js').toString(), 'file:///foo/file.js');
54
+ }
55
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar')).toString(), 'foo://a/foo/bar');
56
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar'), '/file.js').toString(), 'foo://a/foo/bar/file.js');
57
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar'), 'file.js').toString(), 'foo://a/foo/bar/file.js');
58
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar/'), '/file.js').toString(), 'foo://a/foo/bar/file.js');
59
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/'), '/file.js').toString(), 'foo://a/file.js');
60
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar/'), './file.js').toString(), 'foo://a/foo/bar/file.js');
61
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar/'), '/./file.js').toString(), 'foo://a/foo/bar/file.js');
62
+ assert.strictEqual(types.URI.joinPath(types.URI.parse('foo://a/foo/bar/'), '../file.js').toString(), 'foo://a/foo/file.js');
63
+
64
+ assert.strictEqual(
65
+ types.URI.joinPath(types.URI.from({ scheme: 'myScheme', authority: 'authority', path: '/path', query: 'query', fragment: 'fragment' }), '/file.js').toString(),
66
+ 'myScheme://authority/path/file.js?query#fragment');
67
+ });
32
68
  });
33
69
  });
@@ -82,7 +82,7 @@ export class URI extends CodeURI implements theia.Uri {
82
82
  if (!uri.path) {
83
83
  throw new Error('\'joinPath\' called on URI without path');
84
84
  }
85
- const newPath = paths.resolve(uri.path, ...pathSegments);
85
+ const newPath = paths.posix.join(uri.path, ...pathSegments);
86
86
  return new URI(uri.scheme, uri.authority, newPath, uri.query, uri.fragment);
87
87
  }
88
88