@lvce-editor/explorer-view 2.33.0 → 2.34.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.
- package/dist/explorerViewWorkerMain.js +103 -86
- package/package.json +1 -1
|
@@ -1378,6 +1378,12 @@ const join = (pathSeparator, ...parts) => {
|
|
|
1378
1378
|
const getBaseName = (pathSeparator, path) => {
|
|
1379
1379
|
return path.slice(path.lastIndexOf(pathSeparator) + 1);
|
|
1380
1380
|
};
|
|
1381
|
+
const join2 = (path, childPath) => {
|
|
1382
|
+
if (path.endsWith('/')) {
|
|
1383
|
+
return `${path}${childPath}`;
|
|
1384
|
+
}
|
|
1385
|
+
return `${path}/${childPath}`;
|
|
1386
|
+
};
|
|
1381
1387
|
|
|
1382
1388
|
const acceptRename = async state => {
|
|
1383
1389
|
const {
|
|
@@ -2033,6 +2039,16 @@ const expandRecursively = async state => {
|
|
|
2033
2039
|
};
|
|
2034
2040
|
};
|
|
2035
2041
|
|
|
2042
|
+
const focus = state => {
|
|
2043
|
+
if (state.focus) {
|
|
2044
|
+
return state;
|
|
2045
|
+
}
|
|
2046
|
+
return {
|
|
2047
|
+
...state,
|
|
2048
|
+
focus: List
|
|
2049
|
+
};
|
|
2050
|
+
};
|
|
2051
|
+
|
|
2036
2052
|
const focusIndex = (state, index) => {
|
|
2037
2053
|
const {
|
|
2038
2054
|
minLineY,
|
|
@@ -2154,7 +2170,7 @@ const focusPrevious = state => {
|
|
|
2154
2170
|
}
|
|
2155
2171
|
};
|
|
2156
2172
|
|
|
2157
|
-
const commandIds = ['acceptEdit', 'cancelEdit', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'getMouseActions', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleInputBlur', 'handleInputClick', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'selectAll', 'selectDown', 'selectUp', 'setDeltaY', 'setSelectedIndices', 'cancelTypeAhead', 'updateEditingValue', 'handleKeyDown', 'updateIcons'];
|
|
2173
|
+
const commandIds = ['acceptEdit', 'cancelEdit', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'handleInputKeyDown', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'getMouseActions', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleInputBlur', 'handleInputClick', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'selectAll', 'selectDown', 'selectUp', 'setDeltaY', 'setSelectedIndices', 'cancelTypeAhead', 'updateEditingValue', 'handleKeyDown', 'updateIcons'];
|
|
2158
2174
|
|
|
2159
2175
|
const getCommandIds = () => {
|
|
2160
2176
|
return commandIds;
|
|
@@ -2461,7 +2477,7 @@ const handleClickDirectoryExpanded = async (state, dirent, index, keepFocus) =>
|
|
|
2461
2477
|
const newMaxLineY = Math.min(maxLineY, newTotal);
|
|
2462
2478
|
const newMinLineY = newMaxLineY - visibleItems;
|
|
2463
2479
|
const deltaY = newMinLineY * itemHeight;
|
|
2464
|
-
const parts = newDirents.slice(
|
|
2480
|
+
const parts = newDirents.slice(newMinLineY, newMaxLineY);
|
|
2465
2481
|
const {
|
|
2466
2482
|
icons,
|
|
2467
2483
|
newFileIconCache
|
|
@@ -2993,36 +3009,63 @@ const getExpandedDirents = items => {
|
|
|
2993
3009
|
return items.filter(isExpanded);
|
|
2994
3010
|
};
|
|
2995
3011
|
|
|
2996
|
-
const
|
|
2997
|
-
const
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
const nestedItems = await refreshChildDirents(item, pathSeparator, expandedFolders);
|
|
3009
|
-
return [item, ...nestedItems];
|
|
3012
|
+
const getPathDirentsMap = async allPaths => {
|
|
3013
|
+
const pathToDirents = Object.create(null);
|
|
3014
|
+
await Promise.all(allPaths.map(async path => {
|
|
3015
|
+
const dirents = await readDirWithFileTypes(path);
|
|
3016
|
+
pathToDirents[path] = dirents;
|
|
3017
|
+
}));
|
|
3018
|
+
return pathToDirents;
|
|
3019
|
+
};
|
|
3020
|
+
|
|
3021
|
+
const restoreDirentType = (rawDirentType, path, expandedPaths) => {
|
|
3022
|
+
if (rawDirentType === Directory && expandedPaths.includes(path)) {
|
|
3023
|
+
return DirectoryExpanded;
|
|
3010
3024
|
}
|
|
3011
|
-
return
|
|
3025
|
+
return rawDirentType;
|
|
3012
3026
|
};
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
return
|
|
3017
|
-
}
|
|
3018
|
-
|
|
3027
|
+
|
|
3028
|
+
const getProtoMapInternal = (root, pathToDirents, expandedPaths, depth) => {
|
|
3029
|
+
if (!(root in pathToDirents)) {
|
|
3030
|
+
return [];
|
|
3031
|
+
}
|
|
3032
|
+
const items = pathToDirents[root] || [];
|
|
3033
|
+
const protoMap = [];
|
|
3034
|
+
for (let i = 0; i < items.length; i++) {
|
|
3035
|
+
const item = items[i];
|
|
3036
|
+
const path = join2(root, item.name);
|
|
3037
|
+
const displayDirent = {
|
|
3038
|
+
name: item.name,
|
|
3039
|
+
posInSet: i + 1,
|
|
3040
|
+
setSize: items.length,
|
|
3041
|
+
depth,
|
|
3042
|
+
type: restoreDirentType(item.type, path, expandedPaths),
|
|
3043
|
+
path,
|
|
3044
|
+
icon: '',
|
|
3045
|
+
selected: false
|
|
3046
|
+
};
|
|
3047
|
+
const children = getProtoMapInternal(path, pathToDirents, expandedPaths, depth + 1);
|
|
3048
|
+
protoMap.push(displayDirent, ...children);
|
|
3049
|
+
}
|
|
3050
|
+
return protoMap;
|
|
3051
|
+
};
|
|
3052
|
+
|
|
3053
|
+
const getProtoMap = (root, pathToDirents, expandedPaths) => {
|
|
3054
|
+
return getProtoMapInternal(root, pathToDirents, expandedPaths, 1);
|
|
3055
|
+
};
|
|
3056
|
+
|
|
3057
|
+
const sortPathDirentsMap = map => {
|
|
3058
|
+
const sortedMap = Object.create(null);
|
|
3059
|
+
for (const [key, value] of Object.entries(map)) {
|
|
3060
|
+
const sorted = sortExplorerItems(value);
|
|
3061
|
+
sortedMap[key] = sorted;
|
|
3062
|
+
}
|
|
3063
|
+
return sortedMap;
|
|
3019
3064
|
};
|
|
3020
3065
|
|
|
3021
|
-
// TODO add lots of tests for this
|
|
3022
3066
|
const refresh = async state => {
|
|
3023
3067
|
const {
|
|
3024
3068
|
root,
|
|
3025
|
-
pathSeparator,
|
|
3026
3069
|
minLineY,
|
|
3027
3070
|
height,
|
|
3028
3071
|
itemHeight,
|
|
@@ -3030,64 +3073,25 @@ const refresh = async state => {
|
|
|
3030
3073
|
items,
|
|
3031
3074
|
focusedIndex
|
|
3032
3075
|
} = state;
|
|
3033
|
-
|
|
3034
|
-
// Get all expanded folders
|
|
3035
3076
|
const expandedDirents = getExpandedDirents(items);
|
|
3036
|
-
const
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
const
|
|
3040
|
-
const
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
path: root.endsWith(pathSeparator) ? `${root}${dirent.name}` : `${root}${pathSeparator}${dirent.name}`,
|
|
3044
|
-
depth: 0,
|
|
3045
|
-
selected: false
|
|
3046
|
-
}));
|
|
3047
|
-
|
|
3048
|
-
// Process expanded folders in parallel
|
|
3049
|
-
const expandedFolderResults = await Promise.all(expandedFolders.map(async folderPath => {
|
|
3050
|
-
const folderIndex = newDirents.findIndex(item => item.path === folderPath);
|
|
3051
|
-
if (folderIndex !== -1) {
|
|
3052
|
-
const folder = newDirents[folderIndex];
|
|
3053
|
-
if (folder.type === Directory) {
|
|
3054
|
-
const childItems = await refreshChildDirents(folder, pathSeparator, expandedFolders);
|
|
3055
|
-
// @ts-ignore
|
|
3056
|
-
folder.type = DirectoryExpanded;
|
|
3057
|
-
return {
|
|
3058
|
-
folderIndex,
|
|
3059
|
-
childItems
|
|
3060
|
-
};
|
|
3061
|
-
}
|
|
3062
|
-
}
|
|
3063
|
-
return null;
|
|
3064
|
-
}));
|
|
3065
|
-
|
|
3066
|
-
// Insert child items in the correct order
|
|
3067
|
-
let offset = 0;
|
|
3068
|
-
for (const result of expandedFolderResults) {
|
|
3069
|
-
if (result) {
|
|
3070
|
-
const {
|
|
3071
|
-
folderIndex,
|
|
3072
|
-
childItems
|
|
3073
|
-
} = result;
|
|
3074
|
-
newDirents.splice(folderIndex + 1 + offset, 0, ...childItems);
|
|
3075
|
-
offset += childItems.length;
|
|
3076
|
-
}
|
|
3077
|
-
}
|
|
3078
|
-
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
|
|
3079
|
-
const visible = newDirents.slice(minLineY, maxLineY);
|
|
3077
|
+
const expandedPaths = getPaths(expandedDirents);
|
|
3078
|
+
const allPaths = [root, ...expandedPaths];
|
|
3079
|
+
const pathToDirents = await getPathDirentsMap(allPaths);
|
|
3080
|
+
const sortedPathDirents = sortPathDirentsMap(pathToDirents);
|
|
3081
|
+
const newItems = getProtoMap(root, sortedPathDirents, expandedPaths);
|
|
3082
|
+
const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newItems.length);
|
|
3083
|
+
const visible = newItems.slice(minLineY, maxLineY);
|
|
3080
3084
|
const {
|
|
3081
3085
|
icons,
|
|
3082
3086
|
newFileIconCache
|
|
3083
3087
|
} = await getFileIcons(visible, fileIconCache);
|
|
3084
3088
|
let newFocusedIndex = focusedIndex;
|
|
3085
|
-
if (focusedIndex >=
|
|
3086
|
-
newFocusedIndex =
|
|
3089
|
+
if (focusedIndex >= newItems.length) {
|
|
3090
|
+
newFocusedIndex = newItems.length - 1;
|
|
3087
3091
|
}
|
|
3088
3092
|
return {
|
|
3089
3093
|
...state,
|
|
3090
|
-
items:
|
|
3094
|
+
items: newItems,
|
|
3091
3095
|
fileIconCache: newFileIconCache,
|
|
3092
3096
|
icons,
|
|
3093
3097
|
maxLineY,
|
|
@@ -3155,18 +3159,18 @@ const getFileOperations = (root, uploadTree) => {
|
|
|
3155
3159
|
const operations = [];
|
|
3156
3160
|
const processTree = (tree, currentPath) => {
|
|
3157
3161
|
for (const [path, value] of Object.entries(tree)) {
|
|
3158
|
-
const fullPath = currentPath ?
|
|
3162
|
+
const fullPath = currentPath ? join2(currentPath, path) : path;
|
|
3159
3163
|
if (typeof value === 'object') {
|
|
3160
3164
|
operations.push({
|
|
3161
3165
|
type: 'createFolder',
|
|
3162
|
-
path:
|
|
3166
|
+
path: join2(root, fullPath),
|
|
3163
3167
|
text: ''
|
|
3164
3168
|
});
|
|
3165
3169
|
processTree(value, fullPath);
|
|
3166
3170
|
} else if (typeof value === 'string') {
|
|
3167
3171
|
operations.push({
|
|
3168
3172
|
type: 'createFile',
|
|
3169
|
-
path:
|
|
3173
|
+
path: join2(root, fullPath),
|
|
3170
3174
|
text: value
|
|
3171
3175
|
});
|
|
3172
3176
|
}
|
|
@@ -3232,7 +3236,7 @@ const getFileOperationsElectron = async (root, paths, fileHandles) => {
|
|
|
3232
3236
|
const path = paths[i];
|
|
3233
3237
|
operations.push({
|
|
3234
3238
|
type: 'copy',
|
|
3235
|
-
path:
|
|
3239
|
+
path: join2(root, name),
|
|
3236
3240
|
text: '',
|
|
3237
3241
|
from: path
|
|
3238
3242
|
});
|
|
@@ -3440,6 +3444,10 @@ const handleInputClick = state => {
|
|
|
3440
3444
|
return state;
|
|
3441
3445
|
};
|
|
3442
3446
|
|
|
3447
|
+
const handleInputKeyDown = (state, key) => {
|
|
3448
|
+
return state;
|
|
3449
|
+
};
|
|
3450
|
+
|
|
3443
3451
|
const filterByFocusWord = (items, focusedIndex, focusWord) => {
|
|
3444
3452
|
if (items.length === 0) {
|
|
3445
3453
|
return -1;
|
|
@@ -3888,7 +3896,7 @@ const getNewChildDirentsForNewDirent = async (items, depth, parentPath, direntTy
|
|
|
3888
3896
|
existingChildren = childDirents.map((dirent, index) => ({
|
|
3889
3897
|
name: dirent.name,
|
|
3890
3898
|
type: dirent.type,
|
|
3891
|
-
path:
|
|
3899
|
+
path: join2(parentPath, dirent.name),
|
|
3892
3900
|
depth,
|
|
3893
3901
|
selected: false,
|
|
3894
3902
|
posInSet: index + 1,
|
|
@@ -4684,11 +4692,18 @@ const renderEventListeners = () => {
|
|
|
4684
4692
|
return [{
|
|
4685
4693
|
name: HandleInputBlur,
|
|
4686
4694
|
params: ['handleInputBlur']
|
|
4687
|
-
},
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4695
|
+
},
|
|
4696
|
+
// {
|
|
4697
|
+
// name: DomEventListenersFunctions.HandleInputKeyDown,
|
|
4698
|
+
// params: ['handleInputKeyDown'],
|
|
4699
|
+
// stopPropagation: true, // TODO find a way to do this without stopPropagation
|
|
4700
|
+
// },
|
|
4701
|
+
// {
|
|
4702
|
+
// name: DomEventListenersFunctions.HandleListKeyDown,
|
|
4703
|
+
// params: ['handleKeyDown', 'event.key'],
|
|
4704
|
+
// preventDefault: true,
|
|
4705
|
+
// },
|
|
4706
|
+
{
|
|
4692
4707
|
name: HandleListFocus,
|
|
4693
4708
|
params: ['handleFocus', 'event.isTrusted', 'event.target.className']
|
|
4694
4709
|
}, {
|
|
@@ -5088,14 +5103,14 @@ const updateEditingValue = async (state, value, inputSource = User) => {
|
|
|
5088
5103
|
|
|
5089
5104
|
const commandMap = {
|
|
5090
5105
|
'Explorer.acceptEdit': wrapCommand(acceptEdit),
|
|
5091
|
-
'Explorer.handleKeyDown': wrapCommand(handleKeyDown),
|
|
5092
|
-
'Explorer.cancelTypeAhead': wrapCommand(cancelTypeAhead),
|
|
5093
5106
|
'Explorer.cancelEdit': wrapCommand(cancelEdit),
|
|
5107
|
+
'Explorer.cancelTypeAhead': wrapCommand(cancelTypeAhead),
|
|
5094
5108
|
'Explorer.collapseAll': wrapCommand(collapseAll),
|
|
5095
5109
|
'Explorer.copyPath': wrapCommand(copyPath),
|
|
5096
5110
|
'Explorer.copyRelativePath': wrapCommand(copyRelativePath),
|
|
5097
5111
|
'Explorer.expandAll': wrapCommand(expandAll),
|
|
5098
5112
|
'Explorer.expandRecursively': wrapCommand(expandRecursively),
|
|
5113
|
+
'Explorer.focus': wrapCommand(focus),
|
|
5099
5114
|
'Explorer.focusFirst': wrapCommand(focusFirst),
|
|
5100
5115
|
'Explorer.focusIndex': wrapCommand(focusIndex),
|
|
5101
5116
|
'Explorer.focusLast': wrapCommand(focusLast),
|
|
@@ -5123,6 +5138,8 @@ const commandMap = {
|
|
|
5123
5138
|
'Explorer.handleIconThemeChange': wrapCommand(handleIconThemeChange),
|
|
5124
5139
|
'Explorer.handleInputBlur': wrapCommand(handleInputBlur),
|
|
5125
5140
|
'Explorer.handleInputClick': wrapCommand(handleInputClick),
|
|
5141
|
+
'Explorer.handleInputKeyDown': wrapCommand(handleInputKeyDown),
|
|
5142
|
+
'Explorer.handleKeyDown': wrapCommand(handleKeyDown),
|
|
5126
5143
|
'Explorer.handlePaste': wrapCommand(handlePaste),
|
|
5127
5144
|
'Explorer.handlePointerDown': wrapCommand(handlePointerDown),
|
|
5128
5145
|
'Explorer.handleUpload': wrapCommand(handleUpload),
|