@theia/filesystem 1.23.0-next.3 → 1.23.0-next.35

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 (135) hide show
  1. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.d.ts +0 -1
  2. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.d.ts.map +1 -1
  3. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.js +7 -8
  4. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.js.map +1 -1
  5. package/lib/browser/breadcrumbs/filepath-breadcrumbs-contribution.js +4 -4
  6. package/lib/browser/breadcrumbs/filepath-breadcrumbs-contribution.js.map +1 -1
  7. package/lib/browser/download/file-download-command-contribution.js +3 -3
  8. package/lib/browser/download/file-download-command-contribution.js.map +1 -1
  9. package/lib/browser/download/file-download-service.js +4 -4
  10. package/lib/browser/download/file-download-service.js.map +1 -1
  11. package/lib/browser/file-dialog/file-dialog-container.js +1 -1
  12. package/lib/browser/file-dialog/file-dialog-container.js.map +1 -1
  13. package/lib/browser/file-dialog/file-dialog-model.d.ts.map +1 -1
  14. package/lib/browser/file-dialog/file-dialog-model.js +3 -3
  15. package/lib/browser/file-dialog/file-dialog-model.js.map +1 -1
  16. package/lib/browser/file-dialog/file-dialog-service.js +6 -6
  17. package/lib/browser/file-dialog/file-dialog-service.js.map +1 -1
  18. package/lib/browser/file-dialog/file-dialog-tree-filters-renderer.d.ts.map +1 -1
  19. package/lib/browser/file-dialog/file-dialog-tree-filters-renderer.js +3 -3
  20. package/lib/browser/file-dialog/file-dialog-tree-filters-renderer.js.map +1 -1
  21. package/lib/browser/file-dialog/file-dialog-tree.d.ts.map +1 -1
  22. package/lib/browser/file-dialog/file-dialog-tree.js +1 -1
  23. package/lib/browser/file-dialog/file-dialog-tree.js.map +1 -1
  24. package/lib/browser/file-dialog/file-dialog-widget.d.ts +0 -1
  25. package/lib/browser/file-dialog/file-dialog-widget.d.ts.map +1 -1
  26. package/lib/browser/file-dialog/file-dialog-widget.js +4 -5
  27. package/lib/browser/file-dialog/file-dialog-widget.js.map +1 -1
  28. package/lib/browser/file-dialog/file-dialog.d.ts.map +1 -1
  29. package/lib/browser/file-dialog/file-dialog.js +22 -22
  30. package/lib/browser/file-dialog/file-dialog.js.map +1 -1
  31. package/lib/browser/file-dialog/index.js +1 -1
  32. package/lib/browser/file-resource.js +3 -3
  33. package/lib/browser/file-resource.js.map +1 -1
  34. package/lib/browser/file-selection.d.ts.map +1 -1
  35. package/lib/browser/file-selection.js.map +1 -1
  36. package/lib/browser/file-service.d.ts.map +1 -1
  37. package/lib/browser/file-service.js +44 -44
  38. package/lib/browser/file-service.js.map +1 -1
  39. package/lib/browser/file-tree/file-tree-container.d.ts +2 -1
  40. package/lib/browser/file-tree/file-tree-container.d.ts.map +1 -1
  41. package/lib/browser/file-tree/file-tree-container.js +10 -10
  42. package/lib/browser/file-tree/file-tree-container.js.map +1 -1
  43. package/lib/browser/file-tree/file-tree-label-provider.js +3 -3
  44. package/lib/browser/file-tree/file-tree-label-provider.js.map +1 -1
  45. package/lib/browser/file-tree/file-tree-model.d.ts +2 -2
  46. package/lib/browser/file-tree/file-tree-model.d.ts.map +1 -1
  47. package/lib/browser/file-tree/file-tree-model.js +11 -8
  48. package/lib/browser/file-tree/file-tree-model.js.map +1 -1
  49. package/lib/browser/file-tree/file-tree-widget.d.ts +4 -3
  50. package/lib/browser/file-tree/file-tree-widget.d.ts.map +1 -1
  51. package/lib/browser/file-tree/file-tree-widget.js +25 -12
  52. package/lib/browser/file-tree/file-tree-widget.js.map +1 -1
  53. package/lib/browser/file-tree/file-tree.d.ts +2 -2
  54. package/lib/browser/file-tree/file-tree.d.ts.map +1 -1
  55. package/lib/browser/file-tree/file-tree.js +3 -3
  56. package/lib/browser/file-tree/file-tree.js.map +1 -1
  57. package/lib/browser/file-tree/index.js +1 -1
  58. package/lib/browser/file-upload-service.js +17 -17
  59. package/lib/browser/file-upload-service.js.map +1 -1
  60. package/lib/browser/filesystem-frontend-contribution.d.ts +1 -1
  61. package/lib/browser/filesystem-frontend-contribution.js +10 -10
  62. package/lib/browser/filesystem-frontend-contribution.js.map +1 -1
  63. package/lib/browser/filesystem-frontend-module.js +4 -4
  64. package/lib/browser/filesystem-frontend-module.js.map +1 -1
  65. package/lib/browser/filesystem-preferences.js +1 -1
  66. package/lib/browser/filesystem-preferences.js.map +1 -1
  67. package/lib/browser/filesystem-watcher-error-handler.js +3 -3
  68. package/lib/browser/filesystem-watcher-error-handler.js.map +1 -1
  69. package/lib/browser/filesystem-watcher.js +3 -3
  70. package/lib/browser/filesystem-watcher.js.map +1 -1
  71. package/lib/browser/index.js +1 -1
  72. package/lib/browser/location/index.js +1 -1
  73. package/lib/browser/location/location-renderer.d.ts +1 -1
  74. package/lib/browser/location/location-renderer.d.ts.map +1 -1
  75. package/lib/browser/location/location-renderer.js +7 -7
  76. package/lib/browser/location/location-renderer.js.map +1 -1
  77. package/lib/browser/remote-file-service-contribution.js +2 -2
  78. package/lib/browser/remote-file-service-contribution.js.map +1 -1
  79. package/lib/common/delegating-file-system-provider.js +11 -11
  80. package/lib/common/delegating-file-system-provider.js.map +1 -1
  81. package/lib/common/files.d.ts +2 -2
  82. package/lib/common/files.d.ts.map +1 -1
  83. package/lib/common/filesystem-watcher-protocol.js +2 -2
  84. package/lib/common/filesystem-watcher-protocol.js.map +1 -1
  85. package/lib/common/index.js +1 -1
  86. package/lib/common/io.js +4 -4
  87. package/lib/common/io.js.map +1 -1
  88. package/lib/common/remote-file-system-provider.d.ts.map +1 -1
  89. package/lib/common/remote-file-system-provider.js +21 -21
  90. package/lib/common/remote-file-system-provider.js.map +1 -1
  91. package/lib/electron-browser/file-dialog/electron-file-dialog-service.d.ts.map +1 -1
  92. package/lib/electron-browser/file-dialog/electron-file-dialog-service.js +2 -2
  93. package/lib/electron-browser/file-dialog/electron-file-dialog-service.js.map +1 -1
  94. package/lib/node/disk-file-system-provider.js +51 -51
  95. package/lib/node/disk-file-system-provider.js.map +1 -1
  96. package/lib/node/download/directory-archiver.js +2 -2
  97. package/lib/node/download/directory-archiver.js.map +1 -1
  98. package/lib/node/download/directory-archiver.spec.js +8 -8
  99. package/lib/node/download/directory-archiver.spec.js.map +1 -1
  100. package/lib/node/download/file-download-cache.js +2 -2
  101. package/lib/node/download/file-download-cache.js.map +1 -1
  102. package/lib/node/download/file-download-endpoint.js +9 -9
  103. package/lib/node/download/file-download-endpoint.js.map +1 -1
  104. package/lib/node/download/file-download-handler.js +12 -12
  105. package/lib/node/download/file-download-handler.js.map +1 -1
  106. package/lib/node/download/test/mock-directory-archiver.d.ts.map +1 -1
  107. package/lib/node/download/test/mock-directory-archiver.js.map +1 -1
  108. package/lib/node/filesystem-watcher-client.js +3 -3
  109. package/lib/node/filesystem-watcher-client.js.map +1 -1
  110. package/lib/node/filesystem-watcher-dispatcher.js +1 -1
  111. package/lib/node/filesystem-watcher-dispatcher.js.map +1 -1
  112. package/lib/node/node-file-upload-service.js +1 -1
  113. package/lib/node/node-file-upload-service.js.map +1 -1
  114. package/lib/node/nsfw-watcher/nsfw-filesystem-service.js +2 -2
  115. package/lib/node/nsfw-watcher/nsfw-filesystem-service.js.map +1 -1
  116. package/lib/node/nsfw-watcher/nsfw-filesystem-watcher.js +2 -2
  117. package/lib/node/nsfw-watcher/nsfw-filesystem-watcher.js.map +1 -1
  118. package/package.json +3 -3
  119. package/src/browser/breadcrumbs/filepath-breadcrumbs-container.ts +4 -4
  120. package/src/browser/file-dialog/file-dialog-model.ts +6 -6
  121. package/src/browser/file-dialog/file-dialog-tree-filters-renderer.tsx +1 -1
  122. package/src/browser/file-dialog/file-dialog-tree.ts +1 -1
  123. package/src/browser/file-dialog/file-dialog-widget.ts +4 -4
  124. package/src/browser/file-dialog/file-dialog.ts +15 -15
  125. package/src/browser/file-selection.ts +2 -2
  126. package/src/browser/file-service.ts +1 -1
  127. package/src/browser/file-tree/file-tree-container.ts +11 -13
  128. package/src/browser/file-tree/file-tree-model.ts +5 -4
  129. package/src/browser/file-tree/file-tree-widget.tsx +35 -22
  130. package/src/browser/file-tree/file-tree.ts +1 -1
  131. package/src/browser/location/location-renderer.tsx +3 -3
  132. package/src/common/remote-file-system-provider.ts +2 -2
  133. package/src/electron-browser/file-dialog/electron-file-dialog-service.ts +4 -4
  134. package/src/node/download/directory-archiver.spec.ts +1 -1
  135. package/src/node/download/test/mock-directory-archiver.ts +1 -1
@@ -64,7 +64,7 @@ export class FileDialogTreeFiltersRenderer extends ReactRenderer {
64
64
 
65
65
  protected readonly handleFilterChanged = (e: React.ChangeEvent<HTMLSelectElement>) => this.onFilterChanged(e);
66
66
 
67
- protected doRender(): React.ReactNode {
67
+ protected override doRender(): React.ReactNode {
68
68
  if (!this.appliedFilters) {
69
69
  return undefined;
70
70
  }
@@ -37,7 +37,7 @@ export class FileDialogTree extends FileTree {
37
37
  this.refresh();
38
38
  }
39
39
 
40
- protected async toNodes(fileStat: FileStat, parent: CompositeTreeNode): Promise<TreeNode[]> {
40
+ protected override async toNodes(fileStat: FileStat, parent: CompositeTreeNode): Promise<TreeNode[]> {
41
41
  if (!fileStat.children) {
42
42
  return [];
43
43
  }
@@ -28,8 +28,8 @@ export class FileDialogWidget extends FileTreeWidget {
28
28
  private _disableFileSelection: boolean = false;
29
29
 
30
30
  constructor(
31
- @inject(TreeProps) readonly props: TreeProps,
32
- @inject(FileDialogModel) readonly model: FileDialogModel,
31
+ @inject(TreeProps) props: TreeProps,
32
+ @inject(FileDialogModel) override readonly model: FileDialogModel,
33
33
  @inject(ContextMenuRenderer) contextMenuRenderer: ContextMenuRenderer
34
34
  ) {
35
35
  super(props, model, contextMenuRenderer);
@@ -41,7 +41,7 @@ export class FileDialogWidget extends FileTreeWidget {
41
41
  this.model.disableFileSelection = isSelectable;
42
42
  }
43
43
 
44
- protected createNodeAttributes(node: TreeNode, props: NodeProps): React.Attributes & React.HTMLAttributes<HTMLElement> {
44
+ protected override createNodeAttributes(node: TreeNode, props: NodeProps): React.Attributes & React.HTMLAttributes<HTMLElement> {
45
45
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
46
  const attr = super.createNodeAttributes(node, props) as any;
47
47
  if (this.shouldDisableSelection(node)) {
@@ -55,7 +55,7 @@ export class FileDialogWidget extends FileTreeWidget {
55
55
  return attr;
56
56
  }
57
57
 
58
- protected createNodeClassNames(node: TreeNode, props: NodeProps): string[] {
58
+ protected override createNodeClassNames(node: TreeNode, props: NodeProps): string[] {
59
59
  const classNames = super.createNodeClassNames(node, props);
60
60
  if (this.shouldDisableSelection(node)) {
61
61
  [SELECTED_CLASS, FOCUS_CLASS].forEach(name => {
@@ -127,7 +127,7 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
127
127
  @inject(FileDialogTreeFiltersRendererFactory) readonly treeFiltersFactory: FileDialogTreeFiltersRendererFactory;
128
128
 
129
129
  constructor(
130
- @inject(FileDialogProps) readonly props: FileDialogProps
130
+ @inject(FileDialogProps) override readonly props: FileDialogProps
131
131
  ) {
132
132
  super(props);
133
133
  }
@@ -177,7 +177,7 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
177
177
  return this.widget.model;
178
178
  }
179
179
 
180
- protected onUpdateRequest(msg: Message): void {
180
+ protected override onUpdateRequest(msg: Message): void {
181
181
  super.onUpdateRequest(msg);
182
182
  setEnabled(this.back, this.model.canNavigateBackward());
183
183
  setEnabled(this.forward, this.model.canNavigateForward());
@@ -194,14 +194,14 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
194
194
  this.widget.update();
195
195
  }
196
196
 
197
- protected handleEnter(event: KeyboardEvent): boolean | void {
197
+ protected override handleEnter(event: KeyboardEvent): boolean | void {
198
198
  if (event.target instanceof HTMLTextAreaElement || this.targetIsDirectoryInput(event.target) || this.targetIsInputToggle(event.target)) {
199
199
  return false;
200
200
  }
201
201
  this.accept();
202
202
  }
203
203
 
204
- protected handleEscape(event: KeyboardEvent): boolean | void {
204
+ protected override handleEscape(event: KeyboardEvent): boolean | void {
205
205
  if (event.target instanceof HTMLTextAreaElement || this.targetIsDirectoryInput(event.target)) {
206
206
  return false;
207
207
  }
@@ -232,7 +232,7 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
232
232
  }
233
233
  }
234
234
 
235
- protected onAfterAttach(msg: Message): void {
235
+ protected override onAfterAttach(msg: Message): void {
236
236
  Widget.attach(this.treePanel, this.contentNode);
237
237
  this.toDisposeOnDetach.push(Disposable.create(() => {
238
238
  Widget.detach(this.treePanel);
@@ -279,7 +279,7 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
279
279
 
280
280
  protected abstract getAcceptButtonLabel(): string;
281
281
 
282
- protected onActivateRequest(msg: Message): void {
282
+ protected override onActivateRequest(msg: Message): void {
283
283
  this.widget.activate();
284
284
  }
285
285
 
@@ -288,12 +288,12 @@ export abstract class FileDialog<T> extends AbstractDialog<T> {
288
288
  @injectable()
289
289
  export class OpenFileDialog extends FileDialog<MaybeArray<FileStatNode>> {
290
290
 
291
- constructor(@inject(OpenFileDialogProps) readonly props: OpenFileDialogProps) {
291
+ constructor(@inject(OpenFileDialogProps) override readonly props: OpenFileDialogProps) {
292
292
  super(props);
293
293
  }
294
294
 
295
295
  @postConstruct()
296
- init(): void {
296
+ override init(): void {
297
297
  super.init();
298
298
  const { props } = this;
299
299
  if (props.canSelectFiles !== undefined) {
@@ -305,7 +305,7 @@ export class OpenFileDialog extends FileDialog<MaybeArray<FileStatNode>> {
305
305
  return this.props.openLabel ? this.props.openLabel : 'Open';
306
306
  }
307
307
 
308
- protected isValid(value: MaybeArray<FileStatNode>): string {
308
+ protected override isValid(value: MaybeArray<FileStatNode>): string {
309
309
  if (value && !this.props.canSelectMany && value instanceof Array) {
310
310
  return 'You can select only one item';
311
311
  }
@@ -320,7 +320,7 @@ export class OpenFileDialog extends FileDialog<MaybeArray<FileStatNode>> {
320
320
  }
321
321
  }
322
322
 
323
- protected async accept(): Promise<void> {
323
+ protected override async accept(): Promise<void> {
324
324
  const selection = this.value;
325
325
  if (!this.props.canSelectFolders
326
326
  && !Array.isArray(selection)
@@ -340,12 +340,12 @@ export class SaveFileDialog extends FileDialog<URI | undefined> {
340
340
  @inject(LabelProvider)
341
341
  protected readonly labelProvider: LabelProvider;
342
342
 
343
- constructor(@inject(SaveFileDialogProps) readonly props: SaveFileDialogProps) {
343
+ constructor(@inject(SaveFileDialogProps) override readonly props: SaveFileDialogProps) {
344
344
  super(props);
345
345
  }
346
346
 
347
347
  @postConstruct()
348
- init(): void {
348
+ override init(): void {
349
349
  super.init();
350
350
  const { widget } = this;
351
351
  widget.addClass(SAVE_DIALOG_CLASS);
@@ -355,7 +355,7 @@ export class SaveFileDialog extends FileDialog<URI | undefined> {
355
355
  return this.props.saveLabel ? this.props.saveLabel : 'Save';
356
356
  }
357
357
 
358
- protected onUpdateRequest(msg: Message): void {
358
+ protected override onUpdateRequest(msg: Message): void {
359
359
  // Update file name field when changing a selection
360
360
  if (this.fileNameField) {
361
361
  if (this.widget.model.selectedFileStatNodes.length === 1) {
@@ -372,7 +372,7 @@ export class SaveFileDialog extends FileDialog<URI | undefined> {
372
372
  super.onUpdateRequest(msg);
373
373
  }
374
374
 
375
- protected isValid(value: URI | undefined): string | boolean {
375
+ protected override isValid(value: URI | undefined): string | boolean {
376
376
  if (this.fileNameField && this.fileNameField.value) {
377
377
  return '';
378
378
  }
@@ -393,7 +393,7 @@ export class SaveFileDialog extends FileDialog<URI | undefined> {
393
393
  return undefined;
394
394
  }
395
395
 
396
- protected onAfterAttach(msg: Message): void {
396
+ protected override onAfterAttach(msg: Message): void {
397
397
  super.onAfterAttach(msg);
398
398
 
399
399
  const fileNamePanel = document.createElement('div');
@@ -28,8 +28,8 @@ export namespace FileSelection {
28
28
  export class CommandHandler extends SelectionCommandHandler<FileSelection> {
29
29
 
30
30
  constructor(
31
- protected readonly selectionService: SelectionService,
32
- protected readonly options: SelectionCommandHandler.Options<FileSelection>
31
+ protected override readonly selectionService: SelectionService,
32
+ protected override readonly options: SelectionCommandHandler.Options<FileSelection>
33
33
  ) {
34
34
  super(
35
35
  selectionService,
@@ -253,7 +253,7 @@ export class TextFileOperationError extends FileOperationError {
253
253
  constructor(
254
254
  message: string,
255
255
  public textFileOperationResult: TextFileOperationResult,
256
- public options?: ReadTextFileOptions & WriteTextFileOptions
256
+ override options?: ReadTextFileOptions & WriteTextFileOptions
257
257
  ) {
258
258
  super(message, FileOperationResult.FILE_OTHER_ERROR);
259
259
  Object.setPrototypeOf(this, TextFileOperationError.prototype);
@@ -15,24 +15,22 @@
15
15
  ********************************************************************************/
16
16
 
17
17
  import { interfaces, Container } from '@theia/core/shared/inversify';
18
- import { createTreeContainer, Tree, TreeImpl, TreeModel, TreeModelImpl, TreeWidget } from '@theia/core/lib/browser';
18
+ import { CompressedExpansionService, CompressionToggle, createTreeContainer, TreeCompressionService, TreeContainerProps } from '@theia/core/lib/browser';
19
19
  import { FileTree } from './file-tree';
20
20
  import { FileTreeModel } from './file-tree-model';
21
21
  import { FileTreeWidget } from './file-tree-widget';
22
22
 
23
- export function createFileTreeContainer(parent: interfaces.Container): Container {
24
- const child = createTreeContainer(parent);
23
+ const fileTreeDefaults: Partial<TreeContainerProps> = {
24
+ tree: FileTree,
25
+ model: FileTreeModel,
26
+ widget: FileTreeWidget,
27
+ expansionService: CompressedExpansionService,
28
+ };
25
29
 
26
- child.unbind(TreeImpl);
27
- child.bind(FileTree).toSelf();
28
- child.rebind(Tree).toService(FileTree);
29
-
30
- child.unbind(TreeModelImpl);
31
- child.bind(FileTreeModel).toSelf();
32
- child.rebind(TreeModel).toService(FileTreeModel);
33
-
34
- child.unbind(TreeWidget);
35
- child.bind(FileTreeWidget).toSelf();
30
+ export function createFileTreeContainer(parent: interfaces.Container, overrides?: Partial<TreeContainerProps>): Container {
31
+ const child = createTreeContainer(parent, { ...fileTreeDefaults, ...overrides });
32
+ child.bind(CompressionToggle).toConstantValue({ compress: false });
33
+ child.bind(TreeCompressionService).toSelf().inSingletonScope();
36
34
 
37
35
  return child;
38
36
  }
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
18
18
  import URI from '@theia/core/lib/common/uri';
19
- import { CompositeTreeNode, TreeModelImpl, TreeNode, ConfirmDialog } from '@theia/core/lib/browser';
19
+ import { CompositeTreeNode, TreeNode, ConfirmDialog, CompressedTreeModel } from '@theia/core/lib/browser';
20
20
  import { FileStatNode, DirNode, FileNode } from './file-tree';
21
21
  import { LocationService } from '../location';
22
22
  import { LabelProvider } from '@theia/core/lib/browser/label-provider';
@@ -27,7 +27,7 @@ import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
27
27
  import { FileSystemUtils } from '../../common';
28
28
 
29
29
  @injectable()
30
- export class FileTreeModel extends TreeModelImpl implements LocationService {
30
+ export class FileTreeModel extends CompressedTreeModel implements LocationService {
31
31
 
32
32
  @inject(LabelProvider) protected readonly labelProvider: LabelProvider;
33
33
 
@@ -41,7 +41,7 @@ export class FileTreeModel extends TreeModelImpl implements LocationService {
41
41
  protected readonly environments: EnvVariablesServer;
42
42
 
43
43
  @postConstruct()
44
- protected init(): void {
44
+ protected override init(): void {
45
45
  super.init();
46
46
  this.toDispose.push(this.fileService.onDidFilesChange(changes => this.onFilesChanged(changes)));
47
47
  this.toDispose.push(this.fileService.onDidRunOperation(event => this.onDidMove(event)));
@@ -142,7 +142,7 @@ export class FileTreeModel extends TreeModelImpl implements LocationService {
142
142
  const nodes = new Map<string, CompositeTreeNode>();
143
143
  for (const uri of uris) {
144
144
  for (const node of this.getNodesByUri(uri.parent)) {
145
- if (DirNode.is(node) && node.expanded) {
145
+ if (DirNode.is(node) && (node.expanded || (this.compressionToggle.compress && this.compressionService.isCompressionParticipant(node)))) {
146
146
  nodes.set(node.id, node);
147
147
  }
148
148
  }
@@ -172,6 +172,7 @@ export class FileTreeModel extends TreeModelImpl implements LocationService {
172
172
  if (DirNode.is(target) && FileStatNode.is(source)) {
173
173
  const name = source.fileStat.name;
174
174
  const targetUri = target.uri.resolve(name);
175
+ if (source.uri.isEqual(targetUri)) { return; }
175
176
  try {
176
177
  await this.fileService.move(source.uri, targetUri);
177
178
  return targetUri;
@@ -20,7 +20,7 @@ import { DisposableCollection, Disposable } from '@theia/core/lib/common/disposa
20
20
  import URI from '@theia/core/lib/common/uri';
21
21
  import { UriSelection } from '@theia/core/lib/common/selection';
22
22
  import { isCancelled } from '@theia/core/lib/common/cancellation';
23
- import { ContextMenuRenderer, NodeProps, TreeProps, TreeNode, CompositeTreeNode, TreeViewWelcomeWidget } from '@theia/core/lib/browser';
23
+ import { ContextMenuRenderer, NodeProps, TreeProps, TreeNode, CompositeTreeNode, CompressedTreeWidget, CompressedNodeProps } from '@theia/core/lib/browser';
24
24
  import { FileUploadService } from '../file-upload-service';
25
25
  import { DirNode, FileStatNode, FileStatNodeData } from './file-tree';
26
26
  import { FileTreeModel } from './file-tree-model';
@@ -33,7 +33,7 @@ export const DIR_NODE_CLASS = 'theia-DirNode';
33
33
  export const FILE_STAT_ICON_CLASS = 'theia-FileStatIcon';
34
34
 
35
35
  @injectable()
36
- export class FileTreeWidget extends TreeViewWelcomeWidget {
36
+ export class FileTreeWidget extends CompressedTreeWidget {
37
37
 
38
38
  protected readonly toCancelNodeExpansion = new DisposableCollection();
39
39
 
@@ -44,8 +44,8 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
44
44
  protected readonly iconThemeService: IconThemeService;
45
45
 
46
46
  constructor(
47
- @inject(TreeProps) readonly props: TreeProps,
48
- @inject(FileTreeModel) readonly model: FileTreeModel,
47
+ @inject(TreeProps) props: TreeProps,
48
+ @inject(FileTreeModel) override readonly model: FileTreeModel,
49
49
  @inject(ContextMenuRenderer) contextMenuRenderer: ContextMenuRenderer
50
50
  ) {
51
51
  super(props, model, contextMenuRenderer);
@@ -53,7 +53,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
53
53
  this.toDispose.push(this.toCancelNodeExpansion);
54
54
  }
55
55
 
56
- protected createNodeClassNames(node: TreeNode, props: NodeProps): string[] {
56
+ protected override createNodeClassNames(node: TreeNode, props: NodeProps): string[] {
57
57
  const classNames = super.createNodeClassNames(node, props);
58
58
  if (FileStatNode.is(node)) {
59
59
  classNames.push(FILE_STAT_NODE_CLASS);
@@ -64,7 +64,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
64
64
  return classNames;
65
65
  }
66
66
 
67
- protected renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
67
+ protected override renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
68
68
  const icon = this.toNodeIcon(node);
69
69
  if (icon) {
70
70
  return <div className={icon + ' file-icon'}></div>;
@@ -73,7 +73,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
73
73
  return null;
74
74
  }
75
75
 
76
- protected createContainerAttributes(): React.HTMLAttributes<HTMLElement> {
76
+ protected override createContainerAttributes(): React.HTMLAttributes<HTMLElement> {
77
77
  const attrs = super.createContainerAttributes();
78
78
  return {
79
79
  ...attrs,
@@ -84,25 +84,38 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
84
84
  };
85
85
  }
86
86
 
87
- protected createNodeAttributes(node: TreeNode, props: NodeProps): React.Attributes & React.HTMLAttributes<HTMLElement> {
88
- const elementAttrs = super.createNodeAttributes(node, props);
87
+ protected override createNodeAttributes(node: TreeNode, props: NodeProps): React.Attributes & React.HTMLAttributes<HTMLElement> {
89
88
  return {
90
- ...elementAttrs,
91
- draggable: FileStatNode.is(node),
92
- onDragStart: event => this.handleDragStartEvent(node, event),
93
- onDragEnter: event => this.handleDragEnterEvent(node, event),
94
- onDragOver: event => this.handleDragOverEvent(node, event),
95
- onDragLeave: event => this.handleDragLeaveEvent(node, event),
96
- onDrop: event => this.handleDropEvent(node, event),
89
+ ...super.createNodeAttributes(node, props),
90
+ ...this.getNodeDragHandlers(node, props),
97
91
  title: this.getNodeTooltip(node)
98
92
  };
99
93
  }
100
94
 
101
95
  protected getNodeTooltip(node: TreeNode): string | undefined {
102
- const uri = UriSelection.getUri(node);
96
+ const operativeNode = this.compressionService.getCompressionChain(node)?.tail() ?? node;
97
+ const uri = UriSelection.getUri(operativeNode);
103
98
  return uri ? uri.path.toString() : undefined;
104
99
  }
105
100
 
101
+ protected override getCaptionChildEventHandlers(node: TreeNode, props: CompressedNodeProps): React.Attributes & React.HtmlHTMLAttributes<HTMLElement> {
102
+ return {
103
+ ...super.getCaptionChildEventHandlers(node, props),
104
+ ...this.getNodeDragHandlers(node, props),
105
+ };
106
+ }
107
+
108
+ protected getNodeDragHandlers(node: TreeNode, props: CompressedNodeProps): React.Attributes & React.HtmlHTMLAttributes<HTMLElement> {
109
+ return {
110
+ onDragStart: event => this.handleDragStartEvent(node, event),
111
+ onDragEnter: event => this.handleDragEnterEvent(node, event),
112
+ onDragOver: event => this.handleDragOverEvent(node, event),
113
+ onDragLeave: event => this.handleDragLeaveEvent(node, event),
114
+ onDrop: event => this.handleDropEvent(node, event),
115
+ draggable: FileStatNode.is(node),
116
+ };
117
+ }
118
+
106
119
  protected handleDragStartEvent(node: TreeNode, event: React.DragEvent): void {
107
120
  event.stopPropagation();
108
121
  let selectedNodes;
@@ -221,7 +234,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
221
234
  return !!theme && !!theme.hidesExplorerArrows;
222
235
  }
223
236
 
224
- protected renderExpansionToggle(node: TreeNode, props: NodeProps): React.ReactNode {
237
+ protected override renderExpansionToggle(node: TreeNode, props: NodeProps): React.ReactNode {
225
238
  if (this.hidesExplorerArrows) {
226
239
  // eslint-disable-next-line no-null/no-null
227
240
  return null;
@@ -229,7 +242,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
229
242
  return super.renderExpansionToggle(node, props);
230
243
  }
231
244
 
232
- protected getPaddingLeft(node: TreeNode, props: NodeProps): number {
245
+ protected override getPaddingLeft(node: TreeNode, props: NodeProps): number {
233
246
  if (this.hidesExplorerArrows) {
234
247
  // additional left padding instead of top-level expansion toggle
235
248
  return super.getPaddingLeft(node, props) + this.props.leftPadding;
@@ -237,7 +250,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
237
250
  return super.getPaddingLeft(node, props);
238
251
  }
239
252
 
240
- protected needsExpansionTogglePadding(node: TreeNode): boolean {
253
+ protected override needsExpansionTogglePadding(node: TreeNode): boolean {
241
254
  const theme = this.iconThemeService.getDefinition(this.iconThemeService.current);
242
255
  if (theme && (theme.hidesExplorerArrows || (theme.hasFileIcons && !theme.hasFolderIcons))) {
243
256
  return false;
@@ -245,7 +258,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
245
258
  return super.needsExpansionTogglePadding(node);
246
259
  }
247
260
 
248
- protected deflateForStorage(node: TreeNode): object {
261
+ protected override deflateForStorage(node: TreeNode): object {
249
262
  const deflated = super.deflateForStorage(node);
250
263
  if (FileStatNode.is(node) && FileStatNodeData.is(deflated)) {
251
264
  deflated.uri = node.uri.toString();
@@ -256,7 +269,7 @@ export class FileTreeWidget extends TreeViewWelcomeWidget {
256
269
  }
257
270
 
258
271
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
- protected inflateFromStorage(node: any, parent?: TreeNode): TreeNode {
272
+ protected override inflateFromStorage(node: any, parent?: TreeNode): TreeNode {
260
273
  if (FileStatNodeData.is(node)) {
261
274
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
262
275
  const fileStatNode: FileStatNode = node as any;
@@ -34,7 +34,7 @@ export class FileTree extends TreeImpl {
34
34
  @inject(MessageService)
35
35
  protected readonly messagingService: MessageService;
36
36
 
37
- async resolveChildren(parent: CompositeTreeNode): Promise<TreeNode[]> {
37
+ override async resolveChildren(parent: CompositeTreeNode): Promise<TreeNode[]> {
38
38
  if (FileStatNode.is(parent)) {
39
39
  const fileStat = await this.resolveFileStat(parent);
40
40
  if (fileStat) {
@@ -117,7 +117,7 @@ export class LocationListRenderer extends ReactRenderer {
117
117
  this.homeDir = (new URI(homeDirWithPrefix)).path.toString();
118
118
  }
119
119
 
120
- render(): void {
120
+ override render(): void {
121
121
  ReactDOM.render(this.doRender(), this.host, this.doAfterRender);
122
122
  }
123
123
 
@@ -153,7 +153,7 @@ export class LocationListRenderer extends ReactRenderer {
153
153
  protected readonly handleTextInputOnBlur = () => this.toggleToSelectInput();
154
154
  protected readonly handleTextInputMouseDown = (e: React.MouseEvent<HTMLSpanElement>) => this.toggleToTextInputOnMouseDown(e);
155
155
 
156
- protected doRender(): React.ReactElement {
156
+ protected override doRender(): React.ReactElement {
157
157
  return (
158
158
  <>
159
159
  {this.renderInputIcon()}
@@ -372,7 +372,7 @@ export class LocationListRenderer extends ReactRenderer {
372
372
  return undefined;
373
373
  }
374
374
 
375
- dispose(): void {
375
+ override dispose(): void {
376
376
  super.dispose();
377
377
  this.toDisposeOnNewCache.dispose();
378
378
  }
@@ -82,7 +82,7 @@ export const RemoteFileSystemProviderError = ApplicationError.declare(-33005,
82
82
  export class RemoteFileSystemProxyFactory<T extends object> extends JsonRpcProxyFactory<T> {
83
83
 
84
84
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
- protected serializeError(e: any): any {
85
+ protected override serializeError(e: any): any {
86
86
  if (e instanceof FileSystemProviderError) {
87
87
  const { code, name } = e;
88
88
  return super.serializeError(RemoteFileSystemProviderError(e.message, { code, name }, e.stack));
@@ -91,7 +91,7 @@ export class RemoteFileSystemProxyFactory<T extends object> extends JsonRpcProxy
91
91
  }
92
92
 
93
93
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
94
- protected deserializeError(capturedError: Error, e: any): any {
94
+ protected override deserializeError(capturedError: Error, e: any): any {
95
95
  const error = super.deserializeError(capturedError, e);
96
96
  if (RemoteFileSystemProviderError.is(error)) {
97
97
  const fileOperationError = new FileSystemProviderError(error.message, error.data.code);
@@ -44,9 +44,9 @@ export class ElectronFileDialogService extends DefaultFileDialogService {
44
44
 
45
45
  @inject(MessageService) protected readonly messageService: MessageService;
46
46
 
47
- async showOpenDialog(props: OpenFileDialogProps & { canSelectMany: true }, folder?: FileStat): Promise<MaybeArray<URI> | undefined>;
48
- async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<URI | undefined>;
49
- async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<MaybeArray<URI> | undefined> {
47
+ override async showOpenDialog(props: OpenFileDialogProps & { canSelectMany: true }, folder?: FileStat): Promise<MaybeArray<URI> | undefined>;
48
+ override async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<URI | undefined>;
49
+ override async showOpenDialog(props: OpenFileDialogProps, folder?: FileStat): Promise<MaybeArray<URI> | undefined> {
50
50
  const rootNode = await this.getRootNode(folder);
51
51
  if (rootNode) {
52
52
  const { filePaths } = await electronRemote.dialog.showOpenDialog(this.toOpenDialogOptions(rootNode.uri, props));
@@ -62,7 +62,7 @@ export class ElectronFileDialogService extends DefaultFileDialogService {
62
62
  return undefined;
63
63
  }
64
64
 
65
- async showSaveDialog(props: SaveFileDialogProps, folder?: FileStat): Promise<URI | undefined> {
65
+ override async showSaveDialog(props: SaveFileDialogProps, folder?: FileStat): Promise<URI | undefined> {
66
66
  const rootNode = await this.getRootNode(folder);
67
67
  if (rootNode) {
68
68
  const { filePath } = await electronRemote.dialog.showSaveDialog(this.toSaveDialogOptions(rootNode.uri, props));
@@ -45,7 +45,7 @@ describe('directory-archiver', () => {
45
45
  await archiver.archive(fromPath, path.join(toPath, 'output.tar'));
46
46
  expect(fs.existsSync(path.join(toPath, 'output.tar'))).to.be.true;
47
47
  const assertPath = track.mkdirSync('assertPath');
48
- return new Promise(resolve => {
48
+ return new Promise<void>(resolve => {
49
49
  fs.createReadStream(path.join(toPath, 'output.tar')).pipe(extract(assertPath)).on('finish', () => {
50
50
  expect(fs.readdirSync(assertPath).sort()).to.be.deep.equal(['A.txt', 'B.txt']);
51
51
  expect(fs.readFileSync(path.join(assertPath, 'A.txt'), { encoding: 'utf8' })).to.be.equal(fs.readFileSync(path.join(fromPath, 'A.txt'), { encoding: 'utf8' }));
@@ -23,7 +23,7 @@ export class MockDirectoryArchiver extends DirectoryArchiver {
23
23
  super();
24
24
  }
25
25
 
26
- protected async isDir(uri: URI): Promise<boolean> {
26
+ protected override async isDir(uri: URI): Promise<boolean> {
27
27
  return !!this.folders && this.folders.map(u => u.toString()).indexOf(uri.toString()) !== -1;
28
28
  }
29
29