mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-31 19:38:23 +00:00 
			
		
		
		
	Fix issue/PR title edit (#30858)
1. "enter" doesn't work (I think it is the last enter support for #14843) 2. if a branch name contains something like `&`, then the branch selector doesn't update
This commit is contained in:
		| @@ -47,10 +47,18 @@ export function initFootLanguageMenu() { | ||||
|  | ||||
| export function initGlobalEnterQuickSubmit() { | ||||
|   document.addEventListener('keydown', (e) => { | ||||
|     const isQuickSubmitEnter = ((e.ctrlKey && !e.altKey) || e.metaKey) && (e.key === 'Enter'); | ||||
|     if (isQuickSubmitEnter && e.target.matches('textarea')) { | ||||
|       e.preventDefault(); | ||||
|       handleGlobalEnterQuickSubmit(e.target); | ||||
|     if (e.key !== 'Enter') return; | ||||
|     const hasCtrlOrMeta = ((e.ctrlKey || e.metaKey) && !e.altKey); | ||||
|     if (hasCtrlOrMeta && e.target.matches('textarea')) { | ||||
|       if (handleGlobalEnterQuickSubmit(e.target)) { | ||||
|         e.preventDefault(); | ||||
|       } | ||||
|     } else if (e.target.matches('input') && !e.target.closest('form')) { | ||||
|       // input in a normal form could handle Enter key by default, so we only handle the input outside a form | ||||
|       // eslint-disable-next-line unicorn/no-lonely-if | ||||
|       if (handleGlobalEnterQuickSubmit(e.target)) { | ||||
|         e.preventDefault(); | ||||
|       } | ||||
|     } | ||||
|   }); | ||||
| } | ||||
|   | ||||
| @@ -3,16 +3,17 @@ export function handleGlobalEnterQuickSubmit(target) { | ||||
|   if (form) { | ||||
|     if (!form.checkValidity()) { | ||||
|       form.reportValidity(); | ||||
|       return; | ||||
|     } else { | ||||
|       // here use the event to trigger the submit event (instead of calling `submit()` method directly) | ||||
|       // otherwise the `areYouSure` handler won't be executed, then there will be an annoying "confirm to leave" dialog | ||||
|       form.dispatchEvent(new SubmitEvent('submit', {bubbles: true, cancelable: true})); | ||||
|     } | ||||
|  | ||||
|     // here use the event to trigger the submit event (instead of calling `submit()` method directly) | ||||
|     // otherwise the `areYouSure` handler won't be executed, then there will be an annoying "confirm to leave" dialog | ||||
|     form.dispatchEvent(new SubmitEvent('submit', {bubbles: true, cancelable: true})); | ||||
|     return; | ||||
|     return true; | ||||
|   } | ||||
|   form = target.closest('.ui.form'); | ||||
|   if (form) { | ||||
|     form.querySelector('.ui.primary.button')?.click(); | ||||
|     return true; | ||||
|   } | ||||
|   return false; | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkd | ||||
| import {toAbsoluteUrl} from '../utils.js'; | ||||
| import {initDropzone} from './common-global.js'; | ||||
| import {POST, GET} from '../modules/fetch.js'; | ||||
| import {showErrorToast} from '../modules/toast.js'; | ||||
|  | ||||
| const {appSubUrl} = window.config; | ||||
|  | ||||
| @@ -602,85 +603,69 @@ export function initRepoIssueWipToggle() { | ||||
|   }); | ||||
| } | ||||
|  | ||||
| async function pullrequest_targetbranch_change(update_url) { | ||||
|   const targetBranch = $('#pull-target-branch').data('branch'); | ||||
|   const $branchTarget = $('#branch_target'); | ||||
|   if (targetBranch === $branchTarget.text()) { | ||||
|     window.location.reload(); | ||||
|     return false; | ||||
|   } | ||||
|   try { | ||||
|     await POST(update_url, {data: new URLSearchParams({target_branch: targetBranch})}); | ||||
|   } catch (error) { | ||||
|     console.error(error); | ||||
|   } finally { | ||||
|     window.location.reload(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export function initRepoIssueTitleEdit() { | ||||
|   // Edit issue title | ||||
|   const $issueTitle = $('#issue-title'); | ||||
|   const $editInput = $('#edit-title-input input'); | ||||
|   const issueTitleDisplay = document.querySelector('#issue-title-display'); | ||||
|   const issueTitleEditor = document.querySelector('#issue-title-editor'); | ||||
|   if (!issueTitleEditor) return; | ||||
|  | ||||
|   const editTitleToggle = function () { | ||||
|     toggleElem($issueTitle); | ||||
|     toggleElem('.not-in-edit'); | ||||
|     toggleElem('#edit-title-input'); | ||||
|     toggleElem('#pull-desc'); | ||||
|     toggleElem('#pull-desc-edit'); | ||||
|     toggleElem('.in-edit'); | ||||
|     toggleElem('.new-issue-button'); | ||||
|     document.getElementById('issue-title-wrapper')?.classList.toggle('edit-active'); | ||||
|     $editInput[0].focus(); | ||||
|     $editInput[0].select(); | ||||
|     return false; | ||||
|   }; | ||||
|  | ||||
|   $('#edit-title').on('click', editTitleToggle); | ||||
|   $('#cancel-edit-title').on('click', editTitleToggle); | ||||
|   $('#save-edit-title').on('click', editTitleToggle).on('click', async function () { | ||||
|     const pullrequest_target_update_url = this.getAttribute('data-target-update-url'); | ||||
|     if (!$editInput.val().length || $editInput.val() === $issueTitle.text()) { | ||||
|       $editInput.val($issueTitle.text()); | ||||
|       await pullrequest_targetbranch_change(pullrequest_target_update_url); | ||||
|     } else { | ||||
|       try { | ||||
|         const params = new URLSearchParams(); | ||||
|         params.append('title', $editInput.val()); | ||||
|         const response = await POST(this.getAttribute('data-update-url'), {data: params}); | ||||
|         const data = await response.json(); | ||||
|         $editInput.val(data.title); | ||||
|         $issueTitle.text(data.title); | ||||
|         if (pullrequest_target_update_url) { | ||||
|           await pullrequest_targetbranch_change(pullrequest_target_update_url); // it will reload the window | ||||
|         } else { | ||||
|           window.location.reload(); | ||||
|         } | ||||
|       } catch (error) { | ||||
|         console.error(error); | ||||
|       } | ||||
|   const issueTitleInput = issueTitleEditor.querySelector('input'); | ||||
|   const oldTitle = issueTitleInput.getAttribute('data-old-title'); | ||||
|   issueTitleDisplay.querySelector('#issue-title-edit-show').addEventListener('click', () => { | ||||
|     hideElem(issueTitleDisplay); | ||||
|     hideElem('#pull-desc-display'); | ||||
|     showElem(issueTitleEditor); | ||||
|     showElem('#pull-desc-editor'); | ||||
|     if (!issueTitleInput.value.trim()) { | ||||
|       issueTitleInput.value = oldTitle; | ||||
|     } | ||||
|     issueTitleInput.focus(); | ||||
|   }); | ||||
|   issueTitleEditor.querySelector('.ui.cancel.button').addEventListener('click', () => { | ||||
|     hideElem(issueTitleEditor); | ||||
|     hideElem('#pull-desc-editor'); | ||||
|     showElem(issueTitleDisplay); | ||||
|     showElem('#pull-desc-display'); | ||||
|   }); | ||||
|   const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button'); | ||||
|   editSaveButton.addEventListener('click', async () => { | ||||
|     const prTargetUpdateUrl = editSaveButton.getAttribute('data-target-update-url'); | ||||
|     const newTitle = issueTitleInput.value.trim(); | ||||
|     try { | ||||
|       if (newTitle && newTitle !== oldTitle) { | ||||
|         const resp = await POST(editSaveButton.getAttribute('data-update-url'), {data: new URLSearchParams({title: newTitle})}); | ||||
|         if (!resp.ok) { | ||||
|           throw new Error(`Failed to update issue title: ${resp.statusText}`); | ||||
|         } | ||||
|       } | ||||
|       if (prTargetUpdateUrl) { | ||||
|         const newTargetBranch = document.querySelector('#pull-target-branch').getAttribute('data-branch'); | ||||
|         const oldTargetBranch = document.querySelector('#branch_target').textContent; | ||||
|         if (newTargetBranch !== oldTargetBranch) { | ||||
|           const resp = await POST(prTargetUpdateUrl, {data: new URLSearchParams({target_branch: newTargetBranch})}); | ||||
|           if (!resp.ok) { | ||||
|             throw new Error(`Failed to update PR target branch: ${resp.statusText}`); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       window.location.reload(); | ||||
|     } catch (error) { | ||||
|       console.error(error); | ||||
|       showErrorToast(error.message); | ||||
|     } | ||||
|     return false; | ||||
|   }); | ||||
| } | ||||
|  | ||||
| export function initRepoIssueBranchSelect() { | ||||
|   const changeBranchSelect = function () { | ||||
|     const $selectionTextField = $('#pull-target-branch'); | ||||
|  | ||||
|     const baseName = $selectionTextField.data('basename'); | ||||
|     const branchNameNew = $(this).data('branch'); | ||||
|     const branchNameOld = $selectionTextField.data('branch'); | ||||
|  | ||||
|     // Replace branch name to keep translation from HTML template | ||||
|     $selectionTextField.html($selectionTextField.html().replace( | ||||
|       `${baseName}:${branchNameOld}`, | ||||
|       `${baseName}:${branchNameNew}`, | ||||
|     )); | ||||
|     $selectionTextField.data('branch', branchNameNew); // update branch name in setting | ||||
|   }; | ||||
|   $('#branch-select > .item').on('click', changeBranchSelect); | ||||
|   document.querySelector('#branch-select')?.addEventListener('click', (e) => { | ||||
|     const el = e.target.closest('.item[data-branch]'); | ||||
|     if (!el) return; | ||||
|     const pullTargetBranch = document.querySelector('#pull-target-branch'); | ||||
|     const baseName = pullTargetBranch.getAttribute('data-basename'); | ||||
|     const branchNameNew = el.getAttribute('data-branch'); | ||||
|     const branchNameOld = pullTargetBranch.getAttribute('data-branch'); | ||||
|     pullTargetBranch.textContent = pullTargetBranch.textContent.replace(`${baseName}:${branchNameOld}`, `${baseName}:${branchNameNew}`); | ||||
|     pullTargetBranch.setAttribute('data-branch', branchNameNew); | ||||
|   }); | ||||
| } | ||||
|  | ||||
| export function initSingleCommentEditor($commentForm) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user