diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 4ff86b5a66..9396115b0d 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -317,7 +317,7 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b case git.EntryModeBlob: ctx.RenderWithErr(ctx.Tr("repo.editor.directory_is_a_file", fileErr.Path), tplEditFile, &form) default: - ctx.Error(http.StatusInternalServerError, err.Error()) + ctx.RenderWithErr(ctx.Tr("repo.editor.filename_is_invalid", fileErr.Path), tplEditFile, &form) } } else { ctx.Error(http.StatusInternalServerError, err.Error()) diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts index 8bf23fc60e..e4ac9bd2f5 100644 --- a/web_src/js/features/repo-editor.ts +++ b/web_src/js/features/repo-editor.ts @@ -75,18 +75,56 @@ export function initRepoEditor() { } filenameInput.addEventListener('input', function () { const parts = filenameInput.value.split('/'); + const links = Array.from(document.querySelectorAll('.breadcrumb span.section')); + const dividers = Array.from(document.querySelectorAll('.breadcrumb .breadcrumb-divider')); if (parts.length > 1) { + let containSpace = false; for (let i = 0; i < parts.length; ++i) { const value = parts[i]; + const trimValue = value.trim(); + if (trimValue === '..') { + // remove previous tree path + if (links.length > 0) { + const link = links.pop(); + const divider = dividers.pop(); + link.remove(); + divider.remove(); + } + continue; + } if (i < parts.length - 1) { - if (value.length) { - $(`${htmlEscape(value)}`).insertBefore($(filenameInput)); - $('').insertBefore($(filenameInput)); + if (trimValue.length) { + const $link = $(`${htmlEscape(value)}`); + const $divider = $(''); + links.push($link.get(0)); + dividers.push($divider.get(0)); + $link.insertBefore($(filenameInput)); + $divider.insertBefore($(filenameInput)); } } else { filenameInput.value = value; } this.setSelectionRange(0, 0); + containSpace |= (trimValue !== value && trimValue !== ''); + } + let warningDiv = document.querySelector('.ui.warning.message.flash-message.flash-warning.space-related'); + containSpace |= Array.from(links).some((link) => { + const value = link.querySelector('a').textContent; + return value.trim() !== value; + }); + if (containSpace) { + if (!warningDiv) { + warningDiv = document.createElement('div'); + warningDiv.classList.add('ui', 'warning', 'message', 'flash-message', 'flash-warning', 'space-related'); + warningDiv.innerHTML = '

Parent directory contains leading or trailing whitespace.

'; + // Add display 'block' because display is set to 'none' in formantic\build\semantic.css + warningDiv.style.display = 'block'; + const inputContainer = document.querySelector('.repo-editor-header'); + inputContainer.insertAdjacentElement('beforebegin', warningDiv); + } + showElem(warningDiv); + } else if (warningDiv) { + hideElem(warningDiv); } } joinTreePath();