mirror of
https://github.com/go-gitea/gitea
synced 2024-12-22 16:44:26 +00: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:
parent
52b319bc00
commit
7580bd98c1
@ -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');
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user