@lvce-editor/explorer-view 2.32.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.
@@ -356,22 +356,11 @@ class IpcChildWithModuleWorker extends Ipc {
356
356
  const wrap$f = global => {
357
357
  return new IpcChildWithModuleWorker(global);
358
358
  };
359
- const withResolvers = () => {
360
- let _resolve;
361
- const promise = new Promise(resolve => {
362
- _resolve = resolve;
363
- });
364
- return {
365
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
366
- resolve: _resolve,
367
- promise
368
- };
369
- };
370
359
  const waitForFirstMessage = async port => {
371
360
  const {
372
361
  resolve,
373
362
  promise
374
- } = withResolvers();
363
+ } = Promise.withResolvers();
375
364
  port.addEventListener('message', resolve, {
376
365
  once: true
377
366
  });
@@ -442,7 +431,7 @@ const create$4 = (method, params) => {
442
431
  };
443
432
  };
444
433
  const callbacks = Object.create(null);
445
- const set$1 = (id, fn) => {
434
+ const set$3 = (id, fn) => {
446
435
  callbacks[id] = fn;
447
436
  };
448
437
  const get$2 = id => {
@@ -461,7 +450,7 @@ const registerPromise = () => {
461
450
  resolve,
462
451
  promise
463
452
  } = Promise.withResolvers();
464
- set$1(id, resolve);
453
+ set$3(id, resolve);
465
454
  return {
466
455
  id,
467
456
  promise
@@ -993,6 +982,33 @@ const getPaths = items => {
993
982
  return items.map(getPath);
994
983
  };
995
984
 
985
+ const rpcs = Object.create(null);
986
+ const set$5 = (id, rpc) => {
987
+ rpcs[id] = rpc;
988
+ };
989
+ const get$1 = id => {
990
+ return rpcs[id];
991
+ };
992
+ const RendererWorker$1 = 1;
993
+ const invoke$2 = (method, ...params) => {
994
+ const rpc = get$1(RendererWorker$1);
995
+ // @ts-ignore
996
+ return rpc.invoke(method, ...params);
997
+ };
998
+ const set$2 = rpc => {
999
+ set$5(RendererWorker$1, rpc);
1000
+ };
1001
+ const RendererWorker = {
1002
+ __proto__: null,
1003
+ invoke: invoke$2,
1004
+ set: set$2
1005
+ };
1006
+
1007
+ const {
1008
+ invoke,
1009
+ set: set$1
1010
+ } = RendererWorker;
1011
+
996
1012
  const DELTA_EDITING = 100;
997
1013
 
998
1014
  const BlockDevice = 1;
@@ -1010,37 +1026,26 @@ const EditingFile = File + DELTA_EDITING;
1010
1026
  const EditingFolder = Directory + DELTA_EDITING;
1011
1027
  const EditingDirectoryExpanded = DirectoryExpanded + DELTA_EDITING;
1012
1028
 
1013
- const RendererWorker = 1;
1014
-
1015
- const rpcs = Object.create(null);
1016
- const set$3 = (id, rpc) => {
1017
- rpcs[id] = rpc;
1018
- };
1019
- const get$1 = id => {
1020
- return rpcs[id];
1021
- };
1022
-
1023
- const invoke = (method, ...params) => {
1024
- const rpc = get$1(RendererWorker);
1025
- // @ts-ignore
1026
- return rpc.invoke(method, ...params);
1027
- };
1028
-
1029
- const getFileIcon = async name => {
1030
- return invoke('IconTheme.getFileIcon', {
1031
- name
1032
- });
1029
+ const getSimpleType = direntType => {
1030
+ if (direntType === Directory || direntType === DirectoryExpanded || direntType === EditingDirectoryExpanded || direntType === EditingFolder) {
1031
+ return 2;
1032
+ }
1033
+ return 1;
1033
1034
  };
1034
-
1035
- const getFolderIcon = async name => {
1036
- return invoke('IconTheme.getFolderIcon', {
1037
- name
1038
- });
1035
+ const toSimpleIconRequest = request => {
1036
+ return {
1037
+ name: request.name,
1038
+ type: getSimpleType(request.type)
1039
+ };
1039
1040
  };
1040
1041
 
1041
1042
  const requestFileIcons = async requests => {
1042
- const promises = requests.map(request => request.type === File ? getFileIcon(request.name) : getFolderIcon(request.name));
1043
- return Promise.all(promises);
1043
+ if (requests.length === 0) {
1044
+ return [];
1045
+ }
1046
+ const simpleRequests = requests.map(toSimpleIconRequest);
1047
+ const icons = await invoke('IconTheme.getIcons', simpleRequests);
1048
+ return icons;
1044
1049
  };
1045
1050
 
1046
1051
  const updateIconCache = (iconCache, missingRequests, newIcons) => {
@@ -1373,6 +1378,12 @@ const join = (pathSeparator, ...parts) => {
1373
1378
  const getBaseName = (pathSeparator, path) => {
1374
1379
  return path.slice(path.lastIndexOf(pathSeparator) + 1);
1375
1380
  };
1381
+ const join2 = (path, childPath) => {
1382
+ if (path.endsWith('/')) {
1383
+ return `${path}${childPath}`;
1384
+ }
1385
+ return `${path}/${childPath}`;
1386
+ };
1376
1387
 
1377
1388
  const acceptRename = async state => {
1378
1389
  const {
@@ -2028,6 +2039,16 @@ const expandRecursively = async state => {
2028
2039
  };
2029
2040
  };
2030
2041
 
2042
+ const focus = state => {
2043
+ if (state.focus) {
2044
+ return state;
2045
+ }
2046
+ return {
2047
+ ...state,
2048
+ focus: List
2049
+ };
2050
+ };
2051
+
2031
2052
  const focusIndex = (state, index) => {
2032
2053
  const {
2033
2054
  minLineY,
@@ -2149,7 +2170,7 @@ const focusPrevious = state => {
2149
2170
  }
2150
2171
  };
2151
2172
 
2152
- 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'];
2153
2174
 
2154
2175
  const getCommandIds = () => {
2155
2176
  return commandIds;
@@ -2456,7 +2477,7 @@ const handleClickDirectoryExpanded = async (state, dirent, index, keepFocus) =>
2456
2477
  const newMaxLineY = Math.min(maxLineY, newTotal);
2457
2478
  const newMinLineY = newMaxLineY - visibleItems;
2458
2479
  const deltaY = newMinLineY * itemHeight;
2459
- const parts = newDirents.slice(minLineY, maxLineY);
2480
+ const parts = newDirents.slice(newMinLineY, newMaxLineY);
2460
2481
  const {
2461
2482
  icons,
2462
2483
  newFileIconCache
@@ -2988,36 +3009,63 @@ const getExpandedDirents = items => {
2988
3009
  return items.filter(isExpanded);
2989
3010
  };
2990
3011
 
2991
- const refreshChildDirent = async (folder, dirent, pathSeparator, expandedFolders) => {
2992
- const path = folder.path.endsWith(pathSeparator) ? `${folder.path}${dirent.name}` : `${folder.path}${pathSeparator}${dirent.name}`;
2993
- const isExpandedFolder = expandedFolders.includes(path);
2994
- const type = dirent.type === 'directory' ? isExpandedFolder ? DirectoryExpanded : Directory : File;
2995
- const item = {
2996
- name: dirent.name,
2997
- type,
2998
- path,
2999
- depth: folder.depth + 1,
3000
- selected: false
3001
- };
3002
- if (isExpandedFolder) {
3003
- const nestedItems = await refreshChildDirents(item, pathSeparator, expandedFolders);
3004
- 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;
3005
3024
  }
3006
- return [item];
3025
+ return rawDirentType;
3007
3026
  };
3008
- const refreshChildDirents = async (folder, pathSeparator, expandedFolders) => {
3009
- const childDirents = await readDirWithFileTypes(folder.path);
3010
- const childItems = await Promise.all(childDirents.map(async dirent => {
3011
- return refreshChildDirent(folder, dirent, pathSeparator, expandedFolders);
3012
- }));
3013
- return childItems.flat();
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;
3014
3064
  };
3015
3065
 
3016
- // TODO add lots of tests for this
3017
3066
  const refresh = async state => {
3018
3067
  const {
3019
3068
  root,
3020
- pathSeparator,
3021
3069
  minLineY,
3022
3070
  height,
3023
3071
  itemHeight,
@@ -3025,64 +3073,25 @@ const refresh = async state => {
3025
3073
  items,
3026
3074
  focusedIndex
3027
3075
  } = state;
3028
-
3029
- // Get all expanded folders
3030
3076
  const expandedDirents = getExpandedDirents(items);
3031
- const expandedFolders = getPaths(expandedDirents);
3032
-
3033
- // Get top level dirents
3034
- const topLevelDirents = await readDirWithFileTypes(root);
3035
- const newDirents = topLevelDirents.map(dirent => ({
3036
- name: dirent.name,
3037
- type: dirent.type === 'directory' ? Directory : File,
3038
- path: root.endsWith(pathSeparator) ? `${root}${dirent.name}` : `${root}${pathSeparator}${dirent.name}`,
3039
- depth: 0,
3040
- selected: false
3041
- }));
3042
-
3043
- // Process expanded folders in parallel
3044
- const expandedFolderResults = await Promise.all(expandedFolders.map(async folderPath => {
3045
- const folderIndex = newDirents.findIndex(item => item.path === folderPath);
3046
- if (folderIndex !== -1) {
3047
- const folder = newDirents[folderIndex];
3048
- if (folder.type === Directory) {
3049
- const childItems = await refreshChildDirents(folder, pathSeparator, expandedFolders);
3050
- // @ts-ignore
3051
- folder.type = DirectoryExpanded;
3052
- return {
3053
- folderIndex,
3054
- childItems
3055
- };
3056
- }
3057
- }
3058
- return null;
3059
- }));
3060
-
3061
- // Insert child items in the correct order
3062
- let offset = 0;
3063
- for (const result of expandedFolderResults) {
3064
- if (result) {
3065
- const {
3066
- folderIndex,
3067
- childItems
3068
- } = result;
3069
- newDirents.splice(folderIndex + 1 + offset, 0, ...childItems);
3070
- offset += childItems.length;
3071
- }
3072
- }
3073
- const maxLineY = getExplorerMaxLineY(minLineY, height, itemHeight, newDirents.length);
3074
- 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);
3075
3084
  const {
3076
3085
  icons,
3077
3086
  newFileIconCache
3078
3087
  } = await getFileIcons(visible, fileIconCache);
3079
3088
  let newFocusedIndex = focusedIndex;
3080
- if (focusedIndex >= newDirents.length) {
3081
- newFocusedIndex = newDirents.length - 1;
3089
+ if (focusedIndex >= newItems.length) {
3090
+ newFocusedIndex = newItems.length - 1;
3082
3091
  }
3083
3092
  return {
3084
3093
  ...state,
3085
- items: newDirents,
3094
+ items: newItems,
3086
3095
  fileIconCache: newFileIconCache,
3087
3096
  icons,
3088
3097
  maxLineY,
@@ -3150,18 +3159,18 @@ const getFileOperations = (root, uploadTree) => {
3150
3159
  const operations = [];
3151
3160
  const processTree = (tree, currentPath) => {
3152
3161
  for (const [path, value] of Object.entries(tree)) {
3153
- const fullPath = currentPath ? `${currentPath}/${path}` : path;
3162
+ const fullPath = currentPath ? join2(currentPath, path) : path;
3154
3163
  if (typeof value === 'object') {
3155
3164
  operations.push({
3156
3165
  type: 'createFolder',
3157
- path: `${root}/${fullPath}`,
3166
+ path: join2(root, fullPath),
3158
3167
  text: ''
3159
3168
  });
3160
3169
  processTree(value, fullPath);
3161
3170
  } else if (typeof value === 'string') {
3162
3171
  operations.push({
3163
3172
  type: 'createFile',
3164
- path: `${root}/${fullPath}`,
3173
+ path: join2(root, fullPath),
3165
3174
  text: value
3166
3175
  });
3167
3176
  }
@@ -3227,7 +3236,7 @@ const getFileOperationsElectron = async (root, paths, fileHandles) => {
3227
3236
  const path = paths[i];
3228
3237
  operations.push({
3229
3238
  type: 'copy',
3230
- path: `${root}/${name}`,
3239
+ path: join2(root, name),
3231
3240
  text: '',
3232
3241
  from: path
3233
3242
  });
@@ -3435,6 +3444,10 @@ const handleInputClick = state => {
3435
3444
  return state;
3436
3445
  };
3437
3446
 
3447
+ const handleInputKeyDown = (state, key) => {
3448
+ return state;
3449
+ };
3450
+
3438
3451
  const filterByFocusWord = (items, focusedIndex, focusWord) => {
3439
3452
  if (items.length === 0) {
3440
3453
  return -1;
@@ -3883,7 +3896,7 @@ const getNewChildDirentsForNewDirent = async (items, depth, parentPath, direntTy
3883
3896
  existingChildren = childDirents.map((dirent, index) => ({
3884
3897
  name: dirent.name,
3885
3898
  type: dirent.type,
3886
- path: `${parentPath}/${dirent.name}`,
3899
+ path: join2(parentPath, dirent.name),
3887
3900
  depth,
3888
3901
  selected: false,
3889
3902
  posInSet: index + 1,
@@ -4129,11 +4142,6 @@ const renderFocus = (oldState, newState) => {
4129
4142
  return [];
4130
4143
  };
4131
4144
 
4132
- const None$2 = 'none';
4133
- const ToolBar = 'toolbar';
4134
- const Tree = 'tree';
4135
- const TreeItem$1 = 'treeitem';
4136
-
4137
4145
  const Actions = 'Actions';
4138
4146
  const Button$2 = 'Button';
4139
4147
  const ButtonNarrow = 'ButtonNarrow';
@@ -4153,7 +4161,10 @@ const Label = 'Label';
4153
4161
  const ListItems = 'ListItems';
4154
4162
  const MaskIconChevronDown = 'MaskIconChevronDown';
4155
4163
  const MaskIconChevronRight = 'MaskIconChevronRight';
4156
- const TreeItem = 'TreeItem';
4164
+ const ScrollBar = 'ScrollBar';
4165
+ const ScrollBarSmall = 'ScrollBarSmall';
4166
+ const ScrollBarThumb = 'ScrollBarThumb';
4167
+ const TreeItem$1 = 'TreeItem';
4157
4168
  const TreeItemActive = 'TreeItemActive';
4158
4169
  const Viewlet = 'Viewlet';
4159
4170
  const Welcome = 'Welcome';
@@ -4197,6 +4208,12 @@ const text = data => {
4197
4208
  childCount: 0
4198
4209
  };
4199
4210
  };
4211
+ const px = value => {
4212
+ return `${value}px`;
4213
+ };
4214
+ const position = (x, y) => {
4215
+ return `${x}px ${y}px`;
4216
+ };
4200
4217
 
4201
4218
  const Button$1 = 1;
4202
4219
  const Div = 4;
@@ -4204,6 +4221,33 @@ const Input = 6;
4204
4221
  const Img = 17;
4205
4222
  const P = 50;
4206
4223
 
4224
+ const getExplorerWelcomeVirtualDom = isWide => {
4225
+ return [{
4226
+ type: Div,
4227
+ className: mergeClassNames(Viewlet, Explorer),
4228
+ tabIndex: 0,
4229
+ childCount: 1
4230
+ }, {
4231
+ type: Div,
4232
+ className: Welcome,
4233
+ childCount: 2
4234
+ }, {
4235
+ type: P,
4236
+ className: WelcomeMessage,
4237
+ childCount: 1
4238
+ }, text(youHaveNotYetOpenedAFolder()), {
4239
+ type: Button$1,
4240
+ className: mergeClassNames(Button$2, ButtonPrimary, isWide ? ButtonWide : ButtonNarrow),
4241
+ childCount: 1,
4242
+ onClick: HandleClickOpenFolder
4243
+ }, text(openFolder$1())];
4244
+ };
4245
+
4246
+ const None$2 = 'none';
4247
+ const ToolBar = 'toolbar';
4248
+ const Tree = 'tree';
4249
+ const TreeItem = 'treeitem';
4250
+
4207
4251
  const chevronDownVirtualDom = {
4208
4252
  type: Div,
4209
4253
  className: mergeClassNames(Chevron, MaskIconChevronDown),
@@ -4291,7 +4335,7 @@ const getExplorerItemVirtualDom = item => {
4291
4335
  const chevronDom = getChevronVirtualDom(chevron);
4292
4336
  return [{
4293
4337
  type: Div,
4294
- role: TreeItem$1,
4338
+ role: TreeItem,
4295
4339
  className,
4296
4340
  draggable: true,
4297
4341
  title: path,
@@ -4307,28 +4351,6 @@ const getExplorerItemVirtualDom = item => {
4307
4351
  }, ...chevronDom, getFileIconVirtualDom(icon), ...getInputOrLabelDom(isEditing, hasEditingError, name)];
4308
4352
  };
4309
4353
 
4310
- const getExplorerWelcomeVirtualDom = isWide => {
4311
- return [{
4312
- type: Div,
4313
- className: mergeClassNames(Viewlet, Explorer),
4314
- tabIndex: 0,
4315
- childCount: 1
4316
- }, {
4317
- type: Div,
4318
- className: Welcome,
4319
- childCount: 2
4320
- }, {
4321
- type: P,
4322
- className: WelcomeMessage,
4323
- childCount: 1
4324
- }, text(youHaveNotYetOpenedAFolder()), {
4325
- type: Button$1,
4326
- className: mergeClassNames(Button$2, ButtonPrimary, isWide ? ButtonWide : ButtonNarrow),
4327
- childCount: 1,
4328
- onClick: HandleClickOpenFolder
4329
- }, text(openFolder$1())];
4330
- };
4331
-
4332
4354
  const getActiveDescendant = focusedIndex => {
4333
4355
  if (focusedIndex >= 0) {
4334
4356
  return 'TreeItemActive';
@@ -4341,17 +4363,8 @@ const getClassName = (focused, focusedIndex, dropTarget) => {
4341
4363
  const className = mergeClassNames(ListItems, extraClass1, extraClass2);
4342
4364
  return className;
4343
4365
  };
4344
- const parentNode = {
4345
- type: Div,
4346
- childCount: 1,
4347
- className: mergeClassNames(Viewlet, Explorer),
4348
- role: 'none'
4349
- };
4350
- const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused, dropTargets) => {
4351
- if (!root) {
4352
- return getExplorerWelcomeVirtualDom(isWide);
4353
- }
4354
- const dom = [parentNode, {
4366
+ const getListItemsVirtualDom = (visibleItems, focusedIndex, focused, dropTargets) => {
4367
+ const dom = [{
4355
4368
  type: Div,
4356
4369
  className: getClassName(focused, focusedIndex, dropTargets),
4357
4370
  tabIndex: 0,
@@ -4373,6 +4386,50 @@ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused
4373
4386
  return dom;
4374
4387
  };
4375
4388
 
4389
+ const getScrollBarSize = (size, contentSize, minimumSliderSize) => {
4390
+ if (size >= contentSize) {
4391
+ return 0;
4392
+ }
4393
+ return Math.max(Math.round(size ** 2 / contentSize), minimumSliderSize);
4394
+ };
4395
+
4396
+ const getScrollBarVirtualDom = (scrollBarHeight, scrollBarTop) => {
4397
+ const shouldShowScrollbar = scrollBarHeight > 0;
4398
+ if (!shouldShowScrollbar) {
4399
+ return [];
4400
+ }
4401
+ const heightString = px(scrollBarHeight);
4402
+ const translateString = position(0, scrollBarTop);
4403
+ return [{
4404
+ type: Div,
4405
+ className: mergeClassNames(ScrollBar, ScrollBarSmall),
4406
+ childCount: 1
4407
+ }, {
4408
+ type: Div,
4409
+ className: ScrollBarThumb,
4410
+ childCount: 0,
4411
+ height: heightString,
4412
+ translate: translateString
4413
+ }];
4414
+ };
4415
+
4416
+ const parentNode = {
4417
+ type: Div,
4418
+ childCount: 2,
4419
+ className: mergeClassNames(Viewlet, Explorer),
4420
+ role: 'none'
4421
+ };
4422
+ const getExplorerVirtualDom = (visibleItems, focusedIndex, root, isWide, focused, dropTargets, height, contentHeight, scrollTop) => {
4423
+ if (!root) {
4424
+ return getExplorerWelcomeVirtualDom(isWide);
4425
+ }
4426
+ const scrollBarHeight = getScrollBarSize(height, contentHeight, 20);
4427
+ const scrollBarTop = Math.round(scrollTop / contentHeight * height);
4428
+ const scrollBarDom = getScrollBarVirtualDom(scrollBarHeight, scrollBarTop);
4429
+ const dom = [parentNode, ...getListItemsVirtualDom(visibleItems, focusedIndex, focused, dropTargets), ...scrollBarDom];
4430
+ return dom;
4431
+ };
4432
+
4376
4433
  const None$1 = 0;
4377
4434
  const Right = 1;
4378
4435
  const Down = 2;
@@ -4408,8 +4465,8 @@ const getExpandedType = type => {
4408
4465
  }
4409
4466
  };
4410
4467
 
4411
- const focused = mergeClassNames(TreeItem, TreeItemActive);
4412
- const selected = mergeClassNames(TreeItem, TreeItemActive);
4468
+ const focused = mergeClassNames(TreeItem$1, TreeItemActive);
4469
+ const selected = mergeClassNames(TreeItem$1, TreeItemActive);
4413
4470
  const getTreeItemClassName = (isSelected, isFocused) => {
4414
4471
  if (isFocused) {
4415
4472
  return focused;
@@ -4417,7 +4474,7 @@ const getTreeItemClassName = (isSelected, isFocused) => {
4417
4474
  if (isSelected) {
4418
4475
  return selected;
4419
4476
  }
4420
- return TreeItem;
4477
+ return TreeItem$1;
4421
4478
  };
4422
4479
 
4423
4480
  const defaultIndent$1 = 1;
@@ -4488,7 +4545,8 @@ const getVisibleExplorerItems = (items, minLineY, maxLineY, focusedIndex, editin
4488
4545
  const renderItems = (oldState, newState) => {
4489
4546
  const visibleDirents = getVisibleExplorerItems(newState.items, newState.minLineY, newState.maxLineY, newState.focusedIndex, newState.editingIndex, newState.editingType, newState.editingValue, newState.editingErrorMessage, newState.icons, newState.useChevrons, newState.dropTargets, newState.editingIcon);
4490
4547
  const isWide = newState.width > 450;
4491
- const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused, newState.dropTargets);
4548
+ const contentHeight = newState.items.length * newState.itemHeight;
4549
+ const dom = getExplorerVirtualDom(visibleDirents, newState.focusedIndex, newState.root, isWide, newState.focused, newState.dropTargets, newState.height, contentHeight, newState.deltaY);
4492
4550
  return ['Viewlet.setDom2', dom];
4493
4551
  };
4494
4552
 
@@ -4634,11 +4692,18 @@ const renderEventListeners = () => {
4634
4692
  return [{
4635
4693
  name: HandleInputBlur,
4636
4694
  params: ['handleInputBlur']
4637
- }, {
4638
- name: HandleListKeyDown,
4639
- params: ['handleKeyDown', 'event.key'],
4640
- preventDefault: true
4641
- }, {
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
+ {
4642
4707
  name: HandleListFocus,
4643
4708
  params: ['handleFocus', 'event.isTrusted', 'event.target.className']
4644
4709
  }, {
@@ -4840,7 +4905,7 @@ const revealItemHidden = async (state, uri) => {
4840
4905
  }
4841
4906
  const pathPartsToReveal = getPathPartsToReveal(root, pathParts, items);
4842
4907
  const pathPartsChildren = await Promise.all(pathPartsToReveal.map(getPathPartChildren));
4843
- const pathPartsChildrenFlat = pathPartsChildren.flat(1);
4908
+ const pathPartsChildrenFlat = pathPartsChildren.flat();
4844
4909
  const orderedPathParts = orderDirents(pathPartsChildrenFlat);
4845
4910
  const mergedDirents = mergeVisibleWithHiddenItems(items, orderedPathParts);
4846
4911
  const index = getIndex(mergedDirents, uri);
@@ -5038,14 +5103,14 @@ const updateEditingValue = async (state, value, inputSource = User) => {
5038
5103
 
5039
5104
  const commandMap = {
5040
5105
  'Explorer.acceptEdit': wrapCommand(acceptEdit),
5041
- 'Explorer.handleKeyDown': wrapCommand(handleKeyDown),
5042
- 'Explorer.cancelTypeAhead': wrapCommand(cancelTypeAhead),
5043
5106
  'Explorer.cancelEdit': wrapCommand(cancelEdit),
5107
+ 'Explorer.cancelTypeAhead': wrapCommand(cancelTypeAhead),
5044
5108
  'Explorer.collapseAll': wrapCommand(collapseAll),
5045
5109
  'Explorer.copyPath': wrapCommand(copyPath),
5046
5110
  'Explorer.copyRelativePath': wrapCommand(copyRelativePath),
5047
5111
  'Explorer.expandAll': wrapCommand(expandAll),
5048
5112
  'Explorer.expandRecursively': wrapCommand(expandRecursively),
5113
+ 'Explorer.focus': wrapCommand(focus),
5049
5114
  'Explorer.focusFirst': wrapCommand(focusFirst),
5050
5115
  'Explorer.focusIndex': wrapCommand(focusIndex),
5051
5116
  'Explorer.focusLast': wrapCommand(focusLast),
@@ -5073,6 +5138,8 @@ const commandMap = {
5073
5138
  'Explorer.handleIconThemeChange': wrapCommand(handleIconThemeChange),
5074
5139
  'Explorer.handleInputBlur': wrapCommand(handleInputBlur),
5075
5140
  'Explorer.handleInputClick': wrapCommand(handleInputClick),
5141
+ 'Explorer.handleInputKeyDown': wrapCommand(handleInputKeyDown),
5142
+ 'Explorer.handleKeyDown': wrapCommand(handleKeyDown),
5076
5143
  'Explorer.handlePaste': wrapCommand(handlePaste),
5077
5144
  'Explorer.handlePointerDown': wrapCommand(handlePointerDown),
5078
5145
  'Explorer.handleUpload': wrapCommand(handleUpload),
@@ -5112,7 +5179,7 @@ const listen = async () => {
5112
5179
  const rpc = await WebWorkerRpcClient.create({
5113
5180
  commandMap: commandMap
5114
5181
  });
5115
- set$3(RendererWorker, rpc);
5182
+ set$1(rpc);
5116
5183
  };
5117
5184
 
5118
5185
  const main = async () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "2.32.0",
3
+ "version": "2.34.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",