@lvce-editor/explorer-view 7.21.2 → 7.22.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.
@@ -1317,7 +1317,6 @@ const DownArrow = 16;
1317
1317
  const Delete$1 = 18;
1318
1318
  const KeyA = 29;
1319
1319
  const KeyC = 31;
1320
- const KeyV = 50;
1321
1320
  const KeyX = 52;
1322
1321
  const F2 = 58;
1323
1322
  const Star = 131;
@@ -1836,7 +1835,7 @@ const dirname = (pathSeparator, path) => {
1836
1835
  const dirname2 = path => {
1837
1836
  return dirname('/', path);
1838
1837
  };
1839
- const join = (pathSeparator, ...parts) => {
1838
+ const join$1 = (pathSeparator, ...parts) => {
1840
1839
  return parts.join(pathSeparator);
1841
1840
  };
1842
1841
  const getBaseName = (pathSeparator, path) => {
@@ -2338,6 +2337,7 @@ const i18nString = (key, placeholders = emptyObject) => {
2338
2337
  };
2339
2338
 
2340
2339
  const CollapseAllFoldersInExplorer = 'Collapse All Folders in Explorer';
2340
+ const CannotMoveFolderIntoSubfolderOfItself = 'Cannot move folder {PH1} into a subfolder of itself';
2341
2341
  const Copy = 'Copy';
2342
2342
  const CopyPath = 'Copy Path';
2343
2343
  const CopyRelativePath = 'Copy Relative Path';
@@ -2441,6 +2441,11 @@ const fileOrFolderAlreadyExists = name => {
2441
2441
  PH1: name
2442
2442
  });
2443
2443
  };
2444
+ const cannotMoveFolderIntoSubfolderOfItself = folderName => {
2445
+ return i18nString(CannotMoveFolderIntoSubfolderOfItself, {
2446
+ PH1: folderName
2447
+ });
2448
+ };
2444
2449
  const theNameIsNotValid = () => {
2445
2450
  return i18nString(TheNameIsNotValid);
2446
2451
  };
@@ -3019,7 +3024,7 @@ const getFileIcons = async (dirents, fileIconCache) => {
3019
3024
  };
3020
3025
  };
3021
3026
 
3022
- const directoryTypes$1 = new Set([DirectoryExpanded, DirectoryExpanding, EditingDirectoryExpanded]);
3027
+ const directoryTypes$2 = new Set([DirectoryExpanded, DirectoryExpanding, EditingDirectoryExpanded]);
3023
3028
  const getParentPath = (path, pathSeparator) => {
3024
3029
  const index = path.lastIndexOf(pathSeparator);
3025
3030
  if (index === -1) {
@@ -3030,7 +3035,7 @@ const getParentPath = (path, pathSeparator) => {
3030
3035
  const getGitIgnoreCandidateDirs = (root, items, pathSeparator) => {
3031
3036
  const dirs = new Set([root]);
3032
3037
  for (const item of items) {
3033
- if (directoryTypes$1.has(item.type)) {
3038
+ if (directoryTypes$2.has(item.type)) {
3034
3039
  dirs.add(item.path);
3035
3040
  }
3036
3041
  const parent = getParentPath(item.path, pathSeparator);
@@ -4270,10 +4275,6 @@ const getKeyBindings = () => {
4270
4275
  command: 'Explorer.collapseAll',
4271
4276
  key: CtrlCmd | LeftArrow,
4272
4277
  when: FocusExplorer
4273
- }, {
4274
- command: 'Explorer.handlePaste',
4275
- key: CtrlCmd | KeyV,
4276
- when: FocusExplorer
4277
4278
  }, {
4278
4279
  command: 'Explorer.handleCopy',
4279
4280
  key: CtrlCmd | KeyC,
@@ -5962,7 +5963,7 @@ const getFileOperationsElectron = async (root, paths, fileHandles, pathSeparator
5962
5963
  const path = paths[i];
5963
5964
  operations.push({
5964
5965
  from: path,
5965
- path: join(pathSeparator, root, name),
5966
+ path: join$1(pathSeparator, root, name),
5966
5967
  type: Copy$1
5967
5968
  });
5968
5969
  }
@@ -6030,6 +6031,121 @@ const handleDrop$1 = async (state, fileHandles, files, paths) => {
6030
6031
  };
6031
6032
  };
6032
6033
 
6034
+ const directoryTypes$1 = [Directory, DirectoryExpanded, DirectoryExpanding];
6035
+ const isDirectory = item => {
6036
+ return directoryTypes$1.includes(item.type);
6037
+ };
6038
+ const isDescendant = (path, parentPath, pathSeparator) => {
6039
+ const prefix = parentPath.endsWith(pathSeparator) ? parentPath : `${parentPath}${pathSeparator}`;
6040
+ return path.startsWith(prefix);
6041
+ };
6042
+ const join = (parentPath, name, pathSeparator) => {
6043
+ if (parentPath.endsWith(pathSeparator)) {
6044
+ return `${parentPath}${name}`;
6045
+ }
6046
+ return `${parentPath}${pathSeparator}${name}`;
6047
+ };
6048
+ const getTargetFolder = (state, index) => {
6049
+ const {
6050
+ items,
6051
+ pathSeparator,
6052
+ root
6053
+ } = state;
6054
+ if (index === -1) {
6055
+ return root;
6056
+ }
6057
+ const item = items[index];
6058
+ if (!item) {
6059
+ throw new Error('Drop target does not exist');
6060
+ }
6061
+ if (isDirectory(item)) {
6062
+ return item.path;
6063
+ }
6064
+ if (item.type === File) {
6065
+ return dirname(pathSeparator, item.path);
6066
+ }
6067
+ throw new Error('Drop target is not a file or folder');
6068
+ };
6069
+ const getTopLevelSourcePaths = (sourcePaths, pathSeparator) => {
6070
+ const uniquePaths = [...new Set(sourcePaths)];
6071
+ return uniquePaths.filter(path => uniquePaths.every(otherPath => otherPath === path || !isDescendant(path, otherPath, pathSeparator)));
6072
+ };
6073
+ const getMoveOperations = (state, sourcePaths, targetFolder) => {
6074
+ const {
6075
+ items,
6076
+ pathSeparator
6077
+ } = state;
6078
+ const itemByPath = new Map(items.map(item => [item.path, item]));
6079
+ const existingPaths = new Set(itemByPath.keys());
6080
+ const destinationPaths = new Set();
6081
+ const operations = [];
6082
+ for (const sourcePath of getTopLevelSourcePaths(sourcePaths, pathSeparator)) {
6083
+ const sourceItem = itemByPath.get(sourcePath);
6084
+ if (!sourceItem) {
6085
+ throw new Error(`Dragged item no longer exists: ${sourcePath}`);
6086
+ }
6087
+ if (sourcePath === targetFolder) {
6088
+ continue;
6089
+ }
6090
+ if (isDirectory(sourceItem) && isDescendant(targetFolder, sourcePath, pathSeparator)) {
6091
+ throw new Error(cannotMoveFolderIntoSubfolderOfItself(sourceItem.name));
6092
+ }
6093
+ const destinationPath = join(targetFolder, sourceItem.name, pathSeparator);
6094
+ if (destinationPath === sourcePath) {
6095
+ continue;
6096
+ }
6097
+ if (destinationPaths.has(destinationPath) || existingPaths.has(destinationPath)) {
6098
+ throw new Error(fileOrFolderAlreadyExists(sourceItem.name));
6099
+ }
6100
+ destinationPaths.add(destinationPath);
6101
+ operations.push({
6102
+ from: sourcePath,
6103
+ path: destinationPath
6104
+ });
6105
+ }
6106
+ return operations;
6107
+ };
6108
+ const expandTargetFolder = (items, targetFolder) => {
6109
+ return items.map(item => {
6110
+ if (item.path === targetFolder && item.type === Directory) {
6111
+ return {
6112
+ ...item,
6113
+ type: DirectoryExpanded
6114
+ };
6115
+ }
6116
+ return item;
6117
+ });
6118
+ };
6119
+ const handleInternalDrop = async (state, sourcePaths, index) => {
6120
+ const {
6121
+ isReadonly,
6122
+ items
6123
+ } = state;
6124
+ if (isReadonly) {
6125
+ return state;
6126
+ }
6127
+ const targetFolder = getTargetFolder(state, index);
6128
+ const operations = getMoveOperations(state, sourcePaths, targetFolder);
6129
+ if (operations.length === 0) {
6130
+ return {
6131
+ ...state,
6132
+ dropTargets: []
6133
+ };
6134
+ }
6135
+ for (const operation of operations) {
6136
+ await rename$1(operation.from, operation.path);
6137
+ }
6138
+ const expandedItems = expandTargetFolder(items, targetFolder);
6139
+ const updated = await refresh({
6140
+ ...state,
6141
+ items: expandedItems
6142
+ });
6143
+ return {
6144
+ ...updated,
6145
+ dropTargets: []
6146
+ };
6147
+ };
6148
+
6033
6149
  const Electron = 2;
6034
6150
 
6035
6151
  const getModule = isElectron => {
@@ -6042,6 +6158,9 @@ const handleDropRoot = async (state, fileHandles, files, paths) => {
6042
6158
  if (state.isReadonly && state.root !== '') {
6043
6159
  return state;
6044
6160
  }
6161
+ if (fileHandles.length === 0 && paths.length > 0) {
6162
+ return handleInternalDrop(state, paths, -1);
6163
+ }
6045
6164
  const isElectron = state.platform === Electron;
6046
6165
  const fn = getModule(isElectron);
6047
6166
  return fn(state, fileHandles, files, paths);
@@ -6095,6 +6214,9 @@ const handleDropIndex = async (state, fileHandles, files, paths, index) => {
6095
6214
  if (state.isReadonly) {
6096
6215
  return state;
6097
6216
  }
6217
+ if (fileHandles.length === 0 && paths.length > 0) {
6218
+ return handleInternalDrop(state, paths, index);
6219
+ }
6098
6220
  const {
6099
6221
  items
6100
6222
  } = state;
@@ -6132,10 +6254,27 @@ const getDroppedItems = async (itemIds, isElectron) => {
6132
6254
  const paths = files.map(file => file.path);
6133
6255
  return {
6134
6256
  fileHandles,
6135
- paths
6257
+ paths,
6258
+ uris: result.uris
6136
6259
  };
6137
6260
  };
6138
6261
 
6262
+ const getInternalDragPaths = (items, uris) => {
6263
+ if (uris.length === 0) {
6264
+ return [];
6265
+ }
6266
+ const pathByUri = new Map(items.map(item => [ensureUri(item.path), item.path]));
6267
+ const paths = [];
6268
+ for (const uri of uris) {
6269
+ const path = pathByUri.get(uri);
6270
+ if (path === undefined) {
6271
+ return [];
6272
+ }
6273
+ paths.push(path);
6274
+ }
6275
+ return paths;
6276
+ };
6277
+
6139
6278
  const handleDrop = async (state, x, y, fileIds) => {
6140
6279
  if (state.isReadonly && state.root !== '') {
6141
6280
  return state;
@@ -6144,11 +6283,14 @@ const handleDrop = async (state, x, y, fileIds) => {
6144
6283
  const isElectron = state.platform === Electron;
6145
6284
  const {
6146
6285
  fileHandles,
6147
- paths
6286
+ paths,
6287
+ uris
6148
6288
  } = await getDroppedItems(fileIds, isElectron);
6289
+ const internalPaths = getInternalDragPaths(state.items, uris);
6290
+ const droppedPaths = internalPaths.length > 0 ? internalPaths : paths;
6149
6291
  const index = getIndexFromPosition(state, x, y);
6150
6292
  const fn = getDropHandler(index);
6151
- const result = await fn(state, fileHandles, [], paths, index);
6293
+ const result = await fn(state, fileHandles, [], droppedPaths, index);
6152
6294
  return result;
6153
6295
  } catch (error) {
6154
6296
  throw new VError(error, 'Failed to drop files');
@@ -6529,6 +6671,42 @@ const handlePaste = async state => {
6529
6671
  return handlePasteCopy(state, nativeFiles);
6530
6672
  };
6531
6673
 
6674
+ const handleNativePaste = async (state, itemIds) => {
6675
+ const {
6676
+ focusedIndex,
6677
+ isReadonly,
6678
+ platform
6679
+ } = state;
6680
+ if (isReadonly) {
6681
+ return state;
6682
+ }
6683
+ if (itemIds.length === 0) {
6684
+ return handlePaste(state);
6685
+ }
6686
+ try {
6687
+ const isElectron = platform === Electron;
6688
+ const {
6689
+ fileHandles,
6690
+ paths
6691
+ } = await getDroppedItems(itemIds, isElectron);
6692
+ if (isElectron) {
6693
+ const nativePaths = paths.filter(Boolean);
6694
+ if (nativePaths.length === 0) {
6695
+ return handlePaste(state);
6696
+ }
6697
+ return handlePasteCopy(state, {
6698
+ files: nativePaths,
6699
+ source: 'gnomeCopiedFiles',
6700
+ type: 'copy'
6701
+ });
6702
+ }
6703
+ const handleDrop = getDropHandler(focusedIndex);
6704
+ return handleDrop(state, fileHandles, [], paths, focusedIndex);
6705
+ } catch (error) {
6706
+ throw new VError(error, 'Failed to paste native files');
6707
+ }
6708
+ };
6709
+
6532
6710
  const handlePointerDown = (state, button, x, y) => {
6533
6711
  const index = getIndexFromPosition(state, x, y);
6534
6712
  if (button === LeftClick && index === -1) {
@@ -7032,14 +7210,8 @@ const getDragLabel = urls => {
7032
7210
  return String(urls.length);
7033
7211
  };
7034
7212
 
7035
- const toUri = path => {
7036
- if (path.startsWith('file://')) {
7037
- return path;
7038
- }
7039
- return 'file://' + path;
7040
- };
7041
7213
  const getDragData = urls => {
7042
- const data = urls.map(toUri).join('\n');
7214
+ const data = urls.map(ensureUri).join('\n');
7043
7215
  const dragData = [{
7044
7216
  data,
7045
7217
  type: 'text/uri-list'
@@ -7055,6 +7227,7 @@ const getDragData = urls => {
7055
7227
 
7056
7228
  const renderDragData = (oldState, newState) => {
7057
7229
  const {
7230
+ focusedIndex,
7058
7231
  isPointerDown,
7059
7232
  items,
7060
7233
  pointerDownIndex,
@@ -7063,9 +7236,16 @@ const renderDragData = (oldState, newState) => {
7063
7236
  if (!isPointerDown) {
7064
7237
  return [];
7065
7238
  }
7066
- const selected = items.filter((item, index) => item.selected || index === pointerDownIndex);
7067
- const urls = selected.map(item => item.path);
7068
- const dragData = getDragData(urls);
7239
+ const pointerDownItem = items[pointerDownIndex];
7240
+ let draggedItems;
7241
+ if (pointerDownIndex === focusedIndex || pointerDownItem?.selected) {
7242
+ draggedItems = getSelectedItems(items, focusedIndex);
7243
+ } else if (pointerDownItem) {
7244
+ draggedItems = [pointerDownItem];
7245
+ } else {
7246
+ draggedItems = [];
7247
+ }
7248
+ const dragData = getDragData(draggedItems.map(item => item.path));
7069
7249
  return ['Viewlet.setDragData', uid, dragData];
7070
7250
  };
7071
7251
 
@@ -7146,6 +7326,7 @@ const HandleInputClick = 9;
7146
7326
  const HandleKeyDown = 21;
7147
7327
  const HandleListBlur = 11;
7148
7328
  const HandleListFocus = 12;
7329
+ const HandleNativePaste = 26;
7149
7330
  const HandlePointerDown = 14;
7150
7331
  const HandlePointerUp = 25;
7151
7332
  const HandleScrollBarMove = 22;
@@ -7341,6 +7522,7 @@ const getListItemsVirtualDom = (visibleItems, focusedIndex, focused, dropTargets
7341
7522
  onDragStart: HandleDragStart,
7342
7523
  onDrop: HandleDrop,
7343
7524
  onFocus: HandleListFocus,
7525
+ onPaste: HandleNativePaste,
7344
7526
  onPointerDown: HandlePointerDown,
7345
7527
  onPointerUp: HandlePointerUp,
7346
7528
  onWheel: HandleWheel,
@@ -7709,6 +7891,10 @@ const renderEventListeners = () => {
7709
7891
  name: HandleDrop,
7710
7892
  params: ['handleDrop', ClientX, ClientY, DataTransferFiles2],
7711
7893
  preventDefault: true
7894
+ }, {
7895
+ name: HandleNativePaste,
7896
+ params: ['handleNativePaste', 'event.clipboardData.files2'],
7897
+ preventDefault: true
7712
7898
  }, {
7713
7899
  name: HandleDragLeave,
7714
7900
  params: ['handleDragLeave']
@@ -8083,6 +8269,7 @@ const commandMap = {
8083
8269
  'Explorer.handleInputClick': wrapListItemCommand(handleInputClick),
8084
8270
  'Explorer.handleInputKeyDown': wrapListItemCommand(handleInputKeyDown),
8085
8271
  'Explorer.handleKeyDown': wrapListItemCommand(handleKeyDown),
8272
+ 'Explorer.handleNativePaste': wrapListItemCommand(handleNativePaste),
8086
8273
  'Explorer.handlePaste': wrapListItemCommand(handlePaste),
8087
8274
  'Explorer.handlePointerDown': wrapListItemCommand(handlePointerDown),
8088
8275
  'Explorer.handlePointerUp': wrapListItemCommand(handlePointerUp),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "7.21.2",
3
+ "version": "7.22.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",