mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 10:56:10 +01:00 
			
		
		
		
	Fix modal + form abuse (#34921)
See the comment. And due to the abuse, there is a regression: when the modal is hidden, the form will be reset and it can't submit. This PR fixes all problems: keep the modal with form open, and add "loading" indicator.
This commit is contained in:
		| @@ -9,8 +9,9 @@ const fomanticModalFn = $.fn.modal; | ||||
| export function initAriaModalPatch() { | ||||
|   if ($.fn.modal === ariaModalFn) throw new Error('initAriaModalPatch could only be called once'); | ||||
|   $.fn.modal = ariaModalFn; | ||||
|   $.fn.fomanticExt.onModalBeforeHidden = onModalBeforeHidden; | ||||
|   (ariaModalFn as FomanticInitFunction).settings = fomanticModalFn.settings; | ||||
|   $.fn.fomanticExt.onModalBeforeHidden = onModalBeforeHidden; | ||||
|   $.fn.modal.settings.onApprove = onModalApproveDefault; | ||||
| } | ||||
|  | ||||
| // the patched `$.fn.modal` modal function | ||||
| @@ -34,6 +35,29 @@ function ariaModalFn(this: any, ...args: Parameters<FomanticInitFunction>) { | ||||
| function onModalBeforeHidden(this: any) { | ||||
|   const $modal = $(this); | ||||
|   const elModal = $modal[0]; | ||||
|   queryElems(elModal, 'form', (form: HTMLFormElement) => form.reset()); | ||||
|   hideToastsFrom(elModal.closest('.ui.dimmer') ?? document.body); | ||||
|  | ||||
|   // reset the form after the modal is hidden, after other modal events and handlers (e.g. "onApprove", form submit) | ||||
|   setTimeout(() => { | ||||
|     queryElems(elModal, 'form', (form: HTMLFormElement) => form.reset()); | ||||
|   }, 0); | ||||
| } | ||||
|  | ||||
| function onModalApproveDefault(this: any) { | ||||
|   const $modal = $(this); | ||||
|   const selectors = $modal.modal('setting', 'selector'); | ||||
|   const elModal = $modal[0]; | ||||
|   const elApprove = elModal.querySelector(selectors.approve); | ||||
|   const elForm = elApprove?.closest('form'); | ||||
|   if (!elForm) return true; // no form, just allow closing the modal | ||||
|  | ||||
|   // "form-fetch-action" can handle network errors gracefully, | ||||
|   // so keep the modal dialog to make users can re-submit the form if anything wrong happens. | ||||
|   if (elForm.matches('.form-fetch-action')) return false; | ||||
|  | ||||
|   // There is an abuse for the "modal" + "form" combination, the "Approve" button is a traditional form submit button in the form. | ||||
|   // Then "approve" and "submit" occur at the same time, the modal will be closed immediately before the form is submitted. | ||||
|   // So here we prevent the modal from closing automatically by returning false, add the "is-loading" class to the form element. | ||||
|   elForm.classList.add('is-loading'); | ||||
|   return false; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user