mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-03 08:02:36 +09:00 
			
		
		
		
	show warning on navigation if currently editing comment or title (#32920)
This PR fixes the issue https://github.com/go-gitea/gitea/issues/32223 Make the browser to show the confirm popup, as it does with other forms. --------- Co-authored-by: Tim Wundenberg <tim@wundenbergs.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		@@ -139,7 +139,7 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template id="issue-comment-editor-template">
 | 
					<template id="issue-comment-editor-template">
 | 
				
			||||||
	<div class="ui form comment">
 | 
						<form class="ui form comment">
 | 
				
			||||||
		<div class="field">
 | 
							<div class="field">
 | 
				
			||||||
			{{template "shared/combomarkdowneditor" (dict
 | 
								{{template "shared/combomarkdowneditor" (dict
 | 
				
			||||||
				"CustomInit" true
 | 
									"CustomInit" true
 | 
				
			||||||
@@ -158,11 +158,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		<div class="field">
 | 
							<div class="field">
 | 
				
			||||||
			<div class="text right edit">
 | 
								<div class="text right edit">
 | 
				
			||||||
				<button class="ui cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
 | 
									<button type="button" class="ui cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
 | 
				
			||||||
				<button class="ui primary button">{{ctx.Locale.Tr "repo.issues.save"}}</button>
 | 
									<button type="submit" class="ui primary button">{{ctx.Locale.Tr "repo.issues.save"}}</button>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</form>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{template "repo/issue/view_content/reference_issue_dialog" .}}
 | 
					{{template "repo/issue/view_content/reference_issue_dialog" .}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,17 +26,17 @@
 | 
				
			|||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
	{{if $canEditIssueTitle}}
 | 
						{{if $canEditIssueTitle}}
 | 
				
			||||||
	<div class="ui form issue-title tw-hidden" id="issue-title-editor">
 | 
						<form class="ui form issue-title tw-hidden" id="issue-title-editor">
 | 
				
			||||||
		<div class="ui input tw-flex-1">
 | 
							<div class="ui input tw-flex-1">
 | 
				
			||||||
			<input value="{{.Issue.Title}}" data-old-title="{{.Issue.Title}}" maxlength="255" autocomplete="off">
 | 
								<input name="title" value="{{.Issue.Title}}" data-old-title="{{.Issue.Title}}" maxlength="255" autocomplete="off">
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<div class="issue-title-buttons">
 | 
							<div class="issue-title-buttons">
 | 
				
			||||||
			<button class="ui small basic cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
 | 
								<button type="button" class="ui small basic cancel button">{{ctx.Locale.Tr "repo.issues.cancel"}}</button>
 | 
				
			||||||
			<button class="ui small primary button" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/title">
 | 
								<button type="submit" class="ui small primary button" data-update-url="{{$.RepoLink}}/issues/{{.Issue.Index}}/title">
 | 
				
			||||||
				{{ctx.Locale.Tr "repo.issues.save"}}
 | 
									{{ctx.Locale.Tr "repo.issues.save"}}
 | 
				
			||||||
			</button>
 | 
								</button>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	</div>
 | 
						</form>
 | 
				
			||||||
	{{end}}
 | 
						{{end}}
 | 
				
			||||||
	<div class="issue-title-meta">
 | 
						<div class="issue-title-meta">
 | 
				
			||||||
		{{if .HasMerged}}
 | 
							{{if .HasMerged}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@ import {attachRefIssueContextPopup} from './contextpopup.ts';
 | 
				
			|||||||
import {initCommentContent, initMarkupContent} from '../markup/content.ts';
 | 
					import {initCommentContent, initMarkupContent} from '../markup/content.ts';
 | 
				
			||||||
import {triggerUploadStateChanged} from './comp/EditorUpload.ts';
 | 
					import {triggerUploadStateChanged} from './comp/EditorUpload.ts';
 | 
				
			||||||
import {convertHtmlToMarkdown} from '../markup/html2markdown.ts';
 | 
					import {convertHtmlToMarkdown} from '../markup/html2markdown.ts';
 | 
				
			||||||
 | 
					import {applyAreYouSure, reinitializeAreYouSure} from '../vendor/jquery.are-you-sure.ts';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async function tryOnEditContent(e) {
 | 
					async function tryOnEditContent(e) {
 | 
				
			||||||
  const clickTarget = e.target.closest('.edit-content');
 | 
					  const clickTarget = e.target.closest('.edit-content');
 | 
				
			||||||
@@ -48,6 +49,7 @@ async function tryOnEditContent(e) {
 | 
				
			|||||||
        showErrorToast(data.errorMessage);
 | 
					        showErrorToast(data.errorMessage);
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      reinitializeAreYouSure(editContentZone.querySelector('form')); // the form is no longer dirty
 | 
				
			||||||
      editContentZone.setAttribute('data-content-version', data.contentVersion);
 | 
					      editContentZone.setAttribute('data-content-version', data.contentVersion);
 | 
				
			||||||
      if (!data.content) {
 | 
					      if (!data.content) {
 | 
				
			||||||
        renderContent.innerHTML = document.querySelector('#no-content').innerHTML;
 | 
					        renderContent.innerHTML = document.querySelector('#no-content').innerHTML;
 | 
				
			||||||
@@ -86,13 +88,15 @@ async function tryOnEditContent(e) {
 | 
				
			|||||||
  comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
 | 
					  comboMarkdownEditor = getComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
 | 
				
			||||||
  if (!comboMarkdownEditor) {
 | 
					  if (!comboMarkdownEditor) {
 | 
				
			||||||
    editContentZone.innerHTML = document.querySelector('#issue-comment-editor-template').innerHTML;
 | 
					    editContentZone.innerHTML = document.querySelector('#issue-comment-editor-template').innerHTML;
 | 
				
			||||||
 | 
					    const form = editContentZone.querySelector('form');
 | 
				
			||||||
 | 
					    applyAreYouSure(form);
 | 
				
			||||||
    const saveButton = querySingleVisibleElem<HTMLButtonElement>(editContentZone, '.ui.primary.button');
 | 
					    const saveButton = querySingleVisibleElem<HTMLButtonElement>(editContentZone, '.ui.primary.button');
 | 
				
			||||||
    const cancelButton = querySingleVisibleElem<HTMLButtonElement>(editContentZone, '.ui.cancel.button');
 | 
					    const cancelButton = querySingleVisibleElem<HTMLButtonElement>(editContentZone, '.ui.cancel.button');
 | 
				
			||||||
    comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
 | 
					    comboMarkdownEditor = await initComboMarkdownEditor(editContentZone.querySelector('.combo-markdown-editor'));
 | 
				
			||||||
    const syncUiState = () => saveButton.disabled = comboMarkdownEditor.isUploading();
 | 
					    const syncUiState = () => saveButton.disabled = comboMarkdownEditor.isUploading();
 | 
				
			||||||
    comboMarkdownEditor.container.addEventListener(ComboMarkdownEditor.EventUploadStateChanged, syncUiState);
 | 
					    comboMarkdownEditor.container.addEventListener(ComboMarkdownEditor.EventUploadStateChanged, syncUiState);
 | 
				
			||||||
    cancelButton.addEventListener('click', cancelAndReset);
 | 
					    cancelButton.addEventListener('click', cancelAndReset);
 | 
				
			||||||
    saveButton.addEventListener('click', saveAndRefresh);
 | 
					    form.addEventListener('submit', saveAndRefresh);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // FIXME: ideally here should reload content and attachment list from backend for existing editor, to avoid losing data
 | 
					  // FIXME: ideally here should reload content and attachment list from backend for existing editor, to avoid losing data
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -532,7 +532,7 @@ export function initRepoIssueWipToggle() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export function initRepoIssueTitleEdit() {
 | 
					export function initRepoIssueTitleEdit() {
 | 
				
			||||||
  const issueTitleDisplay = document.querySelector('#issue-title-display');
 | 
					  const issueTitleDisplay = document.querySelector('#issue-title-display');
 | 
				
			||||||
  const issueTitleEditor = document.querySelector('#issue-title-editor');
 | 
					  const issueTitleEditor = document.querySelector<HTMLFormElement>('#issue-title-editor');
 | 
				
			||||||
  if (!issueTitleEditor) return;
 | 
					  if (!issueTitleEditor) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const issueTitleInput = issueTitleEditor.querySelector('input');
 | 
					  const issueTitleInput = issueTitleEditor.querySelector('input');
 | 
				
			||||||
@@ -558,7 +558,8 @@ export function initRepoIssueTitleEdit() {
 | 
				
			|||||||
  const prTargetUpdateUrl = pullDescEditor?.getAttribute('data-target-update-url');
 | 
					  const prTargetUpdateUrl = pullDescEditor?.getAttribute('data-target-update-url');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button');
 | 
					  const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button');
 | 
				
			||||||
  editSaveButton.addEventListener('click', async () => {
 | 
					  issueTitleEditor.addEventListener('submit', async (e) => {
 | 
				
			||||||
 | 
					    e.preventDefault();
 | 
				
			||||||
    const newTitle = issueTitleInput.value.trim();
 | 
					    const newTitle = issueTitleInput.value.trim();
 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      if (newTitle && newTitle !== oldTitle) {
 | 
					      if (newTitle && newTitle !== oldTitle) {
 | 
				
			||||||
@@ -577,6 +578,7 @@ export function initRepoIssueTitleEdit() {
 | 
				
			|||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					      issueTitleEditor.classList.remove('dirty');
 | 
				
			||||||
      window.location.reload();
 | 
					      window.location.reload();
 | 
				
			||||||
    } catch (error) {
 | 
					    } catch (error) {
 | 
				
			||||||
      console.error(error);
 | 
					      console.error(error);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								web_src/js/vendor/jquery.are-you-sure.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								web_src/js/vendor/jquery.are-you-sure.ts
									
									
									
									
										vendored
									
									
								
							@@ -2,6 +2,7 @@
 | 
				
			|||||||
// Fork of the upstream module. The only changes are:
 | 
					// Fork of the upstream module. The only changes are:
 | 
				
			||||||
// * use export to make it work with ES6 modules.
 | 
					// * use export to make it work with ES6 modules.
 | 
				
			||||||
// * the addition of `const` to make it strict mode compatible.
 | 
					// * the addition of `const` to make it strict mode compatible.
 | 
				
			||||||
 | 
					// * ignore forms with "ignore-dirty" class, ignore hidden forms (closest('.tw-hidden'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*!
 | 
					/*!
 | 
				
			||||||
 * jQuery Plugin: Are-You-Sure (Dirty Form Detection)
 | 
					 * jQuery Plugin: Are-You-Sure (Dirty Form Detection)
 | 
				
			||||||
@@ -161,10 +162,10 @@ export function initAreYouSure($) {
 | 
				
			|||||||
    if (!settings.silent && !window.aysUnloadSet) {
 | 
					    if (!settings.silent && !window.aysUnloadSet) {
 | 
				
			||||||
      window.aysUnloadSet = true;
 | 
					      window.aysUnloadSet = true;
 | 
				
			||||||
      $(window).bind('beforeunload', function() {
 | 
					      $(window).bind('beforeunload', function() {
 | 
				
			||||||
        const $dirtyForms = $("form").filter('.' + settings.dirtyClass);
 | 
					        const $forms = $("form:not(.ignore-dirty)").filter('.' + settings.dirtyClass);
 | 
				
			||||||
        if ($dirtyForms.length == 0) {
 | 
					        const dirtyFormCount = Array.from($forms).reduce((res, form) => form.closest('.tw-hidden') ? res : res + 1, 0);
 | 
				
			||||||
          return;
 | 
					        if (dirtyFormCount === 0) return;
 | 
				
			||||||
        }
 | 
					
 | 
				
			||||||
        // Prevent multiple prompts - seen on Chrome and IE
 | 
					        // Prevent multiple prompts - seen on Chrome and IE
 | 
				
			||||||
        if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) {
 | 
					        if (navigator.userAgent.toLowerCase().match(/msie|chrome/)) {
 | 
				
			||||||
          if (window.aysHasPrompted) {
 | 
					          if (window.aysHasPrompted) {
 | 
				
			||||||
@@ -199,3 +200,7 @@ export function initAreYouSure($) {
 | 
				
			|||||||
export function applyAreYouSure(selectorOrEl: string|Element|$, opts = {}) {
 | 
					export function applyAreYouSure(selectorOrEl: string|Element|$, opts = {}) {
 | 
				
			||||||
  $(selectorOrEl).areYouSure(opts);
 | 
					  $(selectorOrEl).areYouSure(opts);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function reinitializeAreYouSure(selectorOrEl: string|Element|$) {
 | 
				
			||||||
 | 
					  $(selectorOrEl).trigger('reinitialize.areYouSure');
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user