diff options
Diffstat (limited to 'web_src/js/features/repo-editor.ts')
-rw-r--r-- | web_src/js/features/repo-editor.ts | 70 |
1 files changed, 35 insertions, 35 deletions
diff --git a/web_src/js/features/repo-editor.ts b/web_src/js/features/repo-editor.ts index 64d0402d84..f3ca13460c 100644 --- a/web_src/js/features/repo-editor.ts +++ b/web_src/js/features/repo-editor.ts @@ -1,13 +1,13 @@ -import {htmlEscape} from 'escape-goat'; +import {html, htmlRaw} from '../utils/html.ts'; import {createCodeEditor} from './codeeditor.ts'; import {hideElem, queryElems, showElem, createElementFromHTML} from '../utils/dom.ts'; -import {initMarkupContent} from '../markup/content.ts'; import {attachRefIssueContextPopup} from './contextpopup.ts'; import {POST} from '../modules/fetch.ts'; import {initDropzone} from './dropzone.ts'; import {confirmModal} from './comp/ConfirmModal.ts'; import {applyAreYouSure, ignoreAreYouSure} from '../vendor/jquery.are-you-sure.ts'; import {fomanticQuery} from '../modules/fomantic/base.ts'; +import {submitFormFetchAction} from './common-fetch-action.ts'; function initEditPreviewTab(elForm: HTMLFormElement) { const elTabMenu = elForm.querySelector('.repo-editor-menu'); @@ -38,9 +38,6 @@ export function initRepoEditor() { const dropzoneUpload = document.querySelector<HTMLElement>('.page-content.repository.editor.upload .dropzone'); if (dropzoneUpload) initDropzone(dropzoneUpload); - const editArea = document.querySelector<HTMLTextAreaElement>('.page-content.repository.editor textarea#edit_area'); - if (!editArea) return; - for (const el of queryElems<HTMLInputElement>(document, '.js-quick-pull-choice-option')) { el.addEventListener('input', () => { if (el.value === 'commit-to-new-branch') { @@ -55,6 +52,7 @@ export function initRepoEditor() { } const filenameInput = document.querySelector<HTMLInputElement>('#file-name'); + if (!filenameInput) return; function joinTreePath() { const parts = []; for (const el of document.querySelectorAll('.breadcrumb span.section')) { @@ -89,10 +87,10 @@ export function initRepoEditor() { if (i < parts.length - 1) { if (trimValue.length) { const linkElement = createElementFromHTML( - `<span class="section"><a href="#">${htmlEscape(value)}</a></span>`, + html`<span class="section"><a href="#">${value}</a></span>`, ); const dividerElement = createElementFromHTML( - `<div class="breadcrumb-divider">/</div>`, + html`<div class="breadcrumb-divider">/</div>`, ); links.push(linkElement); dividers.push(dividerElement); @@ -115,7 +113,7 @@ export function initRepoEditor() { if (!warningDiv) { warningDiv = document.createElement('div'); warningDiv.classList.add('ui', 'warning', 'message', 'flash-message', 'flash-warning', 'space-related'); - warningDiv.innerHTML = '<p>File path contains leading or trailing whitespace.</p>'; + warningDiv.innerHTML = html`<p>File path contains leading or trailing whitespace.</p>`; // 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'); @@ -145,32 +143,34 @@ export function initRepoEditor() { }); const elForm = document.querySelector<HTMLFormElement>('.repository.editor .edit.form'); - initEditPreviewTab(elForm); - (async () => { - const editor = await createCodeEditor(editArea, filenameInput); + // on the upload page, there is no editor(textarea) + const editArea = document.querySelector<HTMLTextAreaElement>('.page-content.repository.editor textarea#edit_area'); + if (!editArea) return; - // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage - // to enable or disable the commit button - const commitButton = document.querySelector<HTMLButtonElement>('#commit-button'); - const dirtyFileClass = 'dirty-file'; + // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage + // to enable or disable the commit button + const commitButton = document.querySelector<HTMLButtonElement>('#commit-button'); + const dirtyFileClass = 'dirty-file'; - // Disabling the button at the start - if (document.querySelector<HTMLInputElement>('input[name="page_has_posted"]').value !== 'true') { - commitButton.disabled = true; - } + const syncCommitButtonState = () => { + const dirty = elForm.classList.contains(dirtyFileClass); + commitButton.disabled = !dirty; + }; + // Registering a custom listener for the file path and the file content + // FIXME: it is not quite right here (old bug), it causes double-init, the global areYouSure "dirty" class will also be added + applyAreYouSure(elForm, { + silent: true, + dirtyClass: dirtyFileClass, + fieldSelector: ':input:not(.commit-form-wrapper :input)', + change: syncCommitButtonState, + }); + syncCommitButtonState(); // disable the "commit" button when no content changes - // Registering a custom listener for the file path and the file content - // FIXME: it is not quite right here (old bug), it causes double-init, the global areYouSure "dirty" class will also be added - applyAreYouSure(elForm, { - silent: true, - dirtyClass: dirtyFileClass, - fieldSelector: ':input:not(.commit-form-wrapper :input)', - change($form) { - const dirty = $form[0]?.classList.contains(dirtyFileClass); - commitButton.disabled = !dirty; - }, - }); + initEditPreviewTab(elForm); + + (async () => { + const editor = await createCodeEditor(editArea, filenameInput); // Update the editor from query params, if available, // only after the dirtyFileClass initialization @@ -180,7 +180,7 @@ export function initRepoEditor() { editor.setValue(value); } - commitButton?.addEventListener('click', async (e) => { + commitButton.addEventListener('click', async (e) => { // A modal which asks if an empty file should be committed if (!editArea.value) { e.preventDefault(); @@ -189,15 +189,15 @@ export function initRepoEditor() { content: elForm.getAttribute('data-text-empty-confirm-content'), })) { ignoreAreYouSure(elForm); - elForm.submit(); + submitFormFetchAction(elForm); } } }); })(); } -export function renderPreviewPanelContent(previewPanel: Element, content: string) { - previewPanel.innerHTML = content; - initMarkupContent(); +export function renderPreviewPanelContent(previewPanel: Element, htmlContent: string) { + // the content is from the server, so it is safe to use innerHTML + previewPanel.innerHTML = html`<div class="render-content markup">${htmlRaw(htmlContent)}</div>`; attachRefIssueContextPopup(previewPanel.querySelectorAll('p .ref-issue')); } |