@lvce-editor/explorer-view 5.3.0 → 5.5.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.
@@ -1773,6 +1773,15 @@ const mergeTrees = (a, b) => {
1773
1773
  };
1774
1774
  };
1775
1775
 
1776
+ const refreshWorkspace = async () => {
1777
+ // TODO maybe pass an application id to this?
1778
+ try {
1779
+ await invoke$2('Layout.handleWorkspaceRefresh');
1780
+ } catch {
1781
+ // ignore
1782
+ }
1783
+ };
1784
+
1776
1785
  const treeToArrayInternal = (map, root, items, path, depth) => {
1777
1786
  const children = map[path];
1778
1787
  if (!children) {
@@ -1805,7 +1814,6 @@ const treeToArray = (map, root) => {
1805
1814
 
1806
1815
  const EmptyString = '';
1807
1816
  const Slash$1 = '/';
1808
- const Dot = '.';
1809
1817
  const BackSlash = '\\';
1810
1818
 
1811
1819
  const emptyObject = {};
@@ -1829,7 +1837,6 @@ const Delete = 'Delete';
1829
1837
  const FileNameCannotStartWithSlash = 'A file or folder name cannot start with a slash.';
1830
1838
  const FileOrFolderAlreadyExists = 'A file or folder **{PH1}** already exists at this location. Please choose a different name.';
1831
1839
  const FileOrFolderNameMustBeProvider = 'A file or folder name must be provided.';
1832
- const FileCannotStartWithDot = 'A file or folder name cannot start with a dot.';
1833
1840
  const FileCannotStartWithBackSlash = 'A file or folder name cannot start with a backslash.';
1834
1841
  const FilesExplorer = 'Files Explorer';
1835
1842
  const NewFile$1 = 'New File...';
@@ -1840,6 +1847,7 @@ const OpenInIntegratedTerminal = 'Open in integrated Terminal';
1840
1847
  const Paste = 'Paste';
1841
1848
  const RefreshExplorer = 'Refresh Explorer';
1842
1849
  const Rename = 'Rename';
1850
+ const TheNameIsNotValid = 'The name **{0}** is not valid as a file or folder name. Please choose a different name.';
1843
1851
  const TypeAFileName = 'Type file name. Press Enter to confirm or Escape to cancel.'; // TODO use keybinding
1844
1852
  const YouHaveNotYetOpenedAFolder = 'You have not yet opened a folder';
1845
1853
 
@@ -1897,9 +1905,6 @@ const fileOrFolderNameMustBeProvided = () => {
1897
1905
  const fileCannotStartWithSlash = () => {
1898
1906
  return i18nString(FileNameCannotStartWithSlash);
1899
1907
  };
1900
- const fileCannotStartWithDot = () => {
1901
- return i18nString(FileCannotStartWithDot);
1902
- };
1903
1908
  const fileCannotStartWithBackSlash = () => {
1904
1909
  return i18nString(FileCannotStartWithBackSlash);
1905
1910
  };
@@ -1911,15 +1916,15 @@ const fileOrFolderAlreadyExists = name => {
1911
1916
  PH1: name
1912
1917
  });
1913
1918
  };
1919
+ const theNameIsNotValid = () => {
1920
+ return i18nString(TheNameIsNotValid);
1921
+ };
1914
1922
 
1915
1923
  const validateFileName2 = (name, siblingFileNames = []) => {
1916
1924
  if (!name) {
1917
1925
  const editingErrorMessage = fileOrFolderNameMustBeProvided();
1918
1926
  return editingErrorMessage;
1919
1927
  }
1920
- if (name.startsWith(Dot)) {
1921
- return fileCannotStartWithDot();
1922
- }
1923
1928
  if (name.startsWith(Slash$1)) {
1924
1929
  return fileCannotStartWithSlash();
1925
1930
  }
@@ -1927,6 +1932,16 @@ const validateFileName2 = (name, siblingFileNames = []) => {
1927
1932
  return fileCannotStartWithBackSlash();
1928
1933
  }
1929
1934
 
1935
+ // Disallow reserved directory names
1936
+ if (name === '.' || name === '..' || name === '...') {
1937
+ return theNameIsNotValid();
1938
+ }
1939
+
1940
+ // Disallow any filename starting with ../
1941
+ if (name.startsWith('../')) {
1942
+ return theNameIsNotValid();
1943
+ }
1944
+
1930
1945
  // Check if file already exists
1931
1946
  if (siblingFileNames.includes(name)) {
1932
1947
  return fileOrFolderAlreadyExists(name);
@@ -1969,6 +1984,7 @@ const acceptCreate = async (state, newDirentType) => {
1969
1984
  const newItems = treeToArray(merged, root);
1970
1985
  const dirents = newItems;
1971
1986
  const newFocusedIndex = getIndex(newItems, absolutePath);
1987
+ await refreshWorkspace();
1972
1988
  return {
1973
1989
  ...state,
1974
1990
  items: dirents,
@@ -2088,6 +2104,11 @@ const acceptEdit = async state => {
2088
2104
  }
2089
2105
  };
2090
2106
 
2107
+ const getFocusedIndexCancel = (items, editingIndex) => {
2108
+ const newFocusedIndex = editingIndex > items.length ? items.length - 1 : editingIndex;
2109
+ return newFocusedIndex;
2110
+ };
2111
+
2091
2112
  const isNormalItem = item => {
2092
2113
  return item.type !== EditingFile && item.type !== EditingFolder;
2093
2114
  };
@@ -2098,10 +2119,11 @@ const cancelEditCreate = async (state, keepFocus) => {
2098
2119
  items
2099
2120
  } = state;
2100
2121
  const filteredItems = items.filter(isNormalItem);
2122
+ const newFocusedIndex = getFocusedIndexCancel(items, editingIndex);
2101
2123
  return {
2102
2124
  ...state,
2103
2125
  items: filteredItems,
2104
- focusedIndex: editingIndex,
2126
+ focusedIndex: newFocusedIndex,
2105
2127
  focused: keepFocus,
2106
2128
  editingIndex: -1,
2107
2129
  editingValue: '',
@@ -2134,10 +2156,11 @@ const cancelEditRename = (state, keepFocus) => {
2134
2156
  items
2135
2157
  } = state;
2136
2158
  const newItems = getNewDirentsForCancelRename(items, editingIndex);
2159
+ const newFocusedIndex = getFocusedIndexCancel(items, editingIndex);
2137
2160
  return {
2138
2161
  ...state,
2139
2162
  items: newItems,
2140
- focusedIndex: editingIndex,
2163
+ focusedIndex: newFocusedIndex,
2141
2164
  focused: keepFocus,
2142
2165
  editingIndex: -1,
2143
2166
  editingValue: '',
@@ -2666,7 +2689,7 @@ const isEqual$6 = (oldState, newState) => {
2666
2689
  // TODO compute css more optimized
2667
2690
  // maybe only when items change, and even then not
2668
2691
  // always, but only when it affects the css
2669
- return oldState.errorMessageLeft === newState.errorMessageLeft && oldState.errorMessageTop === newState.errorMessageTop && oldState.maxIndent === newState.maxIndent && oldState.scrollBarActive === newState.scrollBarActive && oldState.scrollBarHeight === newState.scrollBarHeight && oldState.visibleExplorerItems === newState.visibleExplorerItems && oldState.editingErrorMessage === newState.editingErrorMessage;
2692
+ return oldState.editingErrorMessage === newState.editingErrorMessage && oldState.errorMessageLeft === newState.errorMessageLeft && oldState.errorMessageTop === newState.errorMessageTop && oldState.maxIndent === newState.maxIndent && oldState.scrollBarActive === newState.scrollBarActive && oldState.scrollBarHeight === newState.scrollBarHeight && oldState.visibleExplorerItems === newState.visibleExplorerItems && oldState.width === newState.width;
2670
2693
  };
2671
2694
 
2672
2695
  const isEqual$5 = (oldState, newState) => {
@@ -4636,6 +4659,16 @@ const getWorkspacePath = () => {
4636
4659
  return invoke$2('Workspace.getPath');
4637
4660
  };
4638
4661
 
4662
+ const isValid = decoration => {
4663
+ return decoration && typeof decoration.decoration === 'string' && typeof decoration.uri === 'string';
4664
+ };
4665
+ const normalizeDecorations = decorations => {
4666
+ if (!decorations || !Array.isArray(decorations)) {
4667
+ return [];
4668
+ }
4669
+ return decorations.filter(isValid);
4670
+ };
4671
+
4639
4672
  const getFileDecorations = async (scheme, root, maybeUris, decorationsEnabled) => {
4640
4673
  try {
4641
4674
  if (!decorationsEnabled) {
@@ -4649,7 +4682,8 @@ const getFileDecorations = async (scheme, root, maybeUris, decorationsEnabled) =
4649
4682
  const providerId = providerIds.at(-1);
4650
4683
  const uris = ensureUris(maybeUris);
4651
4684
  const decorations = await invoke$1('SourceControl.getFileDecorations', providerId, uris);
4652
- return decorations;
4685
+ const normalized = normalizeDecorations(decorations);
4686
+ return normalized;
4653
4687
  } catch (error) {
4654
4688
  console.error(error);
4655
4689
  return [];
@@ -4840,6 +4874,10 @@ const handleWorkspaceChange = async state => {
4840
4874
  return newState;
4841
4875
  };
4842
4876
 
4877
+ const handleWorkspaceRefresh = async state => {
4878
+ return refresh(state);
4879
+ };
4880
+
4843
4881
  const sendMessagePortToFileSystemWorker = async port => {
4844
4882
  await sendMessagePortToFileSystemWorker$1(port, 0);
4845
4883
  };
@@ -5418,6 +5456,7 @@ const getInputDom = (isEditing, hasEditingError) => {
5418
5456
  ariaLabel: ariaLabel,
5419
5457
  autocapitalize: 'off',
5420
5458
  autocorrect: 'off',
5459
+ autocomplete: 'off',
5421
5460
  childCount: 0,
5422
5461
  className: getInputClassName(hasEditingError),
5423
5462
  id: 'ExplorerInput',
@@ -6128,6 +6167,7 @@ const commandMap = {
6128
6167
  'Explorer.handleUpload': wrapListItemCommand(handleUpload),
6129
6168
  'Explorer.handleWheel': wrapListItemCommand(handleWheel),
6130
6169
  'Explorer.handleWorkspaceChange': wrapListItemCommand(handleWorkspaceChange),
6170
+ 'Explorer.handleWorkspaceRefresh': wrapListItemCommand(handleWorkspaceRefresh),
6131
6171
  'Explorer.loadContent': wrapListItemCommand(loadContent),
6132
6172
  'Explorer.newFile': wrapListItemCommand(newFile),
6133
6173
  'Explorer.newFolder': wrapListItemCommand(newFolder),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/explorer-view",
3
- "version": "5.3.0",
3
+ "version": "5.5.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",