提交 6a356716 编写于 作者: J jeanp413

Update IEditableData.validationMessage return type

上级 65198f7c
......@@ -580,8 +580,7 @@ export interface ITreeViewDataProvider {
}
export interface IEditableData {
validationMessage: (value: string) => string | null;
notificationMessage?: (value: string) => { content: string, severity: Severity } | null;
validationMessage: (value: string) => { content: string, severity: Severity } | null;
placeholder?: string | null;
startingValue?: string | null;
onFinish: (value: string, success: boolean) => void;
......
......@@ -733,18 +733,24 @@ export class ShowOpenedFileInNewWindow extends Action {
}
}
export function validateFileName(item: ExplorerItem, name: string): string | null {
export function validateFileName(item: ExplorerItem, name: string): { content: string, severity: Severity } | null {
// Produce a well formed file name
name = getWellFormedFileName(name);
// Name not provided
if (!name || name.length === 0 || /^\s+$/.test(name)) {
return nls.localize('emptyFileNameError', "A file or folder name must be provided.");
return {
content: nls.localize('emptyFileNameError', "A file or folder name must be provided."),
severity: Severity.Error
};
}
// Relative paths only
if (name[0] === '/' || name[0] === '\\') {
return nls.localize('fileNameStartsWithSlashError', "A file or folder name cannot start with a slash.");
return {
content: nls.localize('fileNameStartsWithSlashError', "A file or folder name cannot start with a slash."),
severity: Severity.Error
};
}
const names = coalesce(name.split(/[\\/]/));
......@@ -754,23 +760,25 @@ export function validateFileName(item: ExplorerItem, name: string): string | nul
// Do not allow to overwrite existing file
const child = parent?.getChild(name);
if (child && child !== item) {
return nls.localize('fileNameExistsError', "A file or folder **{0}** already exists at this location. Please choose a different name.", name);
return {
content: nls.localize('fileNameExistsError', "A file or folder **{0}** already exists at this location. Please choose a different name.", name),
severity: Severity.Error
};
}
}
// Invalid File name
const windowsBasenameValidity = item.resource.scheme === Schemas.file && isWindows;
if (names.some((folderName) => !extpath.isValidBasename(folderName, windowsBasenameValidity))) {
return nls.localize('invalidFileNameError', "The name **{0}** is not valid as a file or folder name. Please choose a different name.", trimLongName(name));
return {
content: nls.localize('invalidFileNameError', "The name **{0}** is not valid as a file or folder name. Please choose a different name.", trimLongName(name)),
severity: Severity.Error
};
}
return null;
}
function fileNameNotificationMessage(name: string): { content: string, severity: Severity } | null {
if (/^\s|\s$/.test(name)) {
if (names.some(name => /^\s|\s$/.test(name))) {
return {
content: nls.localize('fileNameWhitespaceWarning', "Leading or trailing whitespace detected."),
content: nls.localize('fileNameWhitespaceWarning', "Leading or trailing whitespace detected in file or folder name."),
severity: Severity.Warning
};
}
......@@ -794,7 +802,7 @@ export function getWellFormedFileName(filename: string): string {
// Trim tabs
filename = strings.trim(filename, '\t');
// Remove trailing dots, slashes, and spaces
// Remove trailing dots and slashes
filename = strings.rtrim(filename, '.');
filename = strings.rtrim(filename, '/');
filename = strings.rtrim(filename, '\\');
......@@ -917,7 +925,6 @@ async function openExplorerAndCreate(accessor: ServicesAccessor, isFolder: boole
explorerService.setEditable(newStat, {
validationMessage: value => validateFileName(newStat, value),
notificationMessage: value => fileNameNotificationMessage(value),
onFinish: (value, success) => {
folder.removeChild(newStat);
explorerService.setEditable(newStat, null);
......@@ -955,7 +962,6 @@ export const renameHandler = (accessor: ServicesAccessor) => {
explorerService.setEditable(stat, {
validationMessage: value => validateFileName(stat, value),
notificationMessage: value => fileNameNotificationMessage(value),
onFinish: async (value, success) => {
if (success) {
const parentResource = stat.parent!.resource;
......
......@@ -375,13 +375,13 @@ export class FilesRenderer implements ICompressibleTreeRenderer<ExplorerItem, Fu
const inputBox = new InputBox(label.element, this.contextViewService, {
validationOptions: {
validation: (value) => {
const content = editableData.validationMessage(value);
if (!content) {
const message = editableData.validationMessage(value);
if (!message || message.severity !== Severity.Error) {
return null;
}
return {
content,
content: message.content,
formatContent: true,
type: MessageType.ERROR
};
......@@ -408,8 +408,8 @@ export class FilesRenderer implements ICompressibleTreeRenderer<ExplorerItem, Fu
});
const showInputBoxNotification = () => {
if (editableData.notificationMessage && inputBox.isInputValid()) {
const message = editableData.notificationMessage(inputBox.value);
if (inputBox.isInputValid()) {
const message = editableData.validationMessage(inputBox.value);
if (message) {
inputBox.showMessage({
content: message.content,
......
......@@ -28,7 +28,7 @@ import { IMenuService, MenuId, IMenu, MenuRegistry, MenuItemAction } from 'vs/pl
import { createAndFillInContextMenuActions, createAndFillInActionBarActions, ContextAwareMenuEntryActionViewItem } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IRemoteExplorerService, TunnelModel, MakeAddress, TunnelType, ITunnelItem, Tunnel } from 'vs/workbench/services/remote/common/remoteExplorerService';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
import { attachInputBoxStyler } from 'vs/platform/theme/common/styler';
import { once } from 'vs/base/common/functional';
......@@ -282,13 +282,13 @@ class TunnelTreeRenderer extends Disposable implements ITreeRenderer<ITunnelGrou
ariaLabel: nls.localize('remote.tunnelsView.input', "Press Enter to confirm or Escape to cancel."),
validationOptions: {
validation: (value) => {
const content = editableData.validationMessage(value);
if (!content) {
const message = editableData.validationMessage(value);
if (!message || message.severity !== Severity.Error) {
return null;
}
return {
content,
content: message.content,
formatContent: true,
type: MessageType.ERROR
};
......@@ -733,7 +733,17 @@ namespace ForwardPortAction {
}
remoteExplorerService.setEditable(undefined, null);
},
validationMessage: validateInput,
validationMessage: (value) => {
const validationString = validateInput(value);
if (!validationString) {
return null;
}
return {
content: validationString,
severity: Severity.Error
};
},
placeholder: forwardPrompt
});
}
......@@ -916,7 +926,17 @@ namespace ChangeLocalPortAction {
}
}
},
validationMessage: validateInput,
validationMessage: (value) => {
const validationString = validateInput(value);
if (!validationString) {
return null;
}
return {
content: validationString,
severity: Severity.Error
};
},
placeholder: nls.localize('remote.tunnelsView.changePort', "New local port")
});
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册