From 1c894c0605d8f25ba6a2aa8a94a805bb8bdd9c69 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 17 May 2022 03:30:26 +0800 Subject: [PATCH 1/3] Make Ctrl+Enter (quick submit) work for issue comment and wiki editor --- web_src/js/features/common-global.js | 12 ++++++++++-- web_src/js/features/comp/EasyMDE.js | 21 ++++++++++++++++++++- web_src/js/features/repo-legacy.js | 10 ++++++++-- web_src/js/features/repo-wiki.js | 15 +++++++++++---- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js index eb21a4bb9313a..f071a98b34d69 100644 --- a/web_src/js/features/common-global.js +++ b/web_src/js/features/common-global.js @@ -44,9 +44,17 @@ export function initFootLanguageMenu() { export function initGlobalEnterQuickSubmit() { - $('.js-quick-submit').on('keydown', function (e) { + $(document).on('keydown', '.js-quick-submit', function (e) { if (((e.ctrlKey && !e.altKey) || e.metaKey) && (e.keyCode === 13 || e.keyCode === 10)) { - $(this).closest('form').trigger('submit'); + const $form = $(this).closest('form'); + // the same logic as `codeMirrorQuickSubmit` function + if ($form.length) { + // here must use jQuery to trigger the submit event, otherwise the `areYouSure` handler won't be executed, then there will be an annoying "confirm to leave" dialog + $form.trigger('submit'); + } else { + // if no form, then the editor is for an AJAX request, we dispatch an event to the target, let the target's event handler to do the AJAX request. + $(e.target).trigger('ce-quick-submit'); + } } }); } diff --git a/web_src/js/features/comp/EasyMDE.js b/web_src/js/features/comp/EasyMDE.js index 0327a1e0238c0..8f9444805b07e 100644 --- a/web_src/js/features/comp/EasyMDE.js +++ b/web_src/js/features/comp/EasyMDE.js @@ -71,9 +71,12 @@ export async function createCommentEasyMDE(textarea, easyMDEOptions = {}) { title: 'Revert to simple textarea', }, ], ...easyMDEOptions}); + const inputField = easyMDE.codemirror.getInputField(); - inputField.classList.add('js-quick-submit'); + easyMDE.codemirror.setOption('extraKeys', { + 'Cmd-Enter': codeMirrorQuickSubmit, + 'Ctrl-Enter': codeMirrorQuickSubmit, Enter: (cm) => { const tributeContainer = document.querySelector('.tribute-container'); if (!tributeContainer || tributeContainer.style.display === 'none') { @@ -149,3 +152,19 @@ export function validateTextareaNonEmpty($textarea) { $mdeInputField.prop('required', false); return true; } + +/** + * @param {CodeMirror.EditorFromTextArea} codeMirror + */ +export function codeMirrorQuickSubmit(codeMirror) { + const textarea = codeMirror.getTextArea(); + const form = textarea.closest('form'); + // the same logic as the global `.js-quick-submit` handler. + if (form) { + // here must use jQuery to trigger the submit event, otherwise the `areYouSure` handler won't be executed, then there will be an annoying "confirm to leave" dialog + $(form).trigger('submit'); + } else { + // if no form, then the editor is for an AJAX request, we dispatch an event to the textarea, let the textarea's event handler to do the AJAX request. + textarea.dispatchEvent(new CustomEvent('ce-quick-submit')); + } +} diff --git a/web_src/js/features/repo-legacy.js b/web_src/js/features/repo-legacy.js index a24d1b974a02a..53471b30cfdff 100644 --- a/web_src/js/features/repo-legacy.js +++ b/web_src/js/features/repo-legacy.js @@ -355,6 +355,11 @@ async function onEditContent(event) { initEasyMDEImagePaste(easyMDE, $dropzone[0], $dropzone.find('.files')); } + const $saveButton = $editContentZone.find('.save.button'); + $textarea.on('ce-quick-submit', () => { + $saveButton.trigger('click'); + }); + $editContentZone.find('.cancel.button').on('click', () => { $renderContent.show(); $editContentZone.hide(); @@ -362,7 +367,8 @@ async function onEditContent(event) { dz.emit('reload'); } }); - $editContentZone.find('.save.button').on('click', () => { + + $saveButton.on('click', () => { $renderContent.show(); $editContentZone.hide(); const $attachments = $dropzone.find('.files').find('[name=files]').map(function () { @@ -400,7 +406,7 @@ async function onEditContent(event) { initCommentContent(); }); }); - } else { + } else { // use existing form $textarea = $segment.find('textarea'); easyMDE = getAttachedEasyMDE($textarea); } diff --git a/web_src/js/features/repo-wiki.js b/web_src/js/features/repo-wiki.js index 0ac88e3f5a659..c3eb26315c9dd 100644 --- a/web_src/js/features/repo-wiki.js +++ b/web_src/js/features/repo-wiki.js @@ -1,6 +1,11 @@ import $ from 'jquery'; import {initMarkupContent} from '../markup/content.js'; -import {attachEasyMDEToElements, importEasyMDE, validateTextareaNonEmpty} from './comp/EasyMDE.js'; +import { + attachEasyMDEToElements, + codeMirrorQuickSubmit, + importEasyMDE, + validateTextareaNonEmpty, +} from './comp/EasyMDE.js'; import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js'; const {csrfToken} = window.config; @@ -122,10 +127,12 @@ async function initRepoWikiFormEditor() { ] }); - attachEasyMDEToElements(easyMDE); + easyMDE.codemirror.setOption('extraKeys', { + 'Cmd-Enter': codeMirrorQuickSubmit, + 'Ctrl-Enter': codeMirrorQuickSubmit, + }); - const $mdeInputField = $(easyMDE.codemirror.getInputField()); - $mdeInputField.addClass('js-quick-submit'); + attachEasyMDEToElements(easyMDE); $form.on('submit', () => { if (!validateTextareaNonEmpty($editArea)) { From cf430d6d0ee6e797f8ec877627eff4deed089e05 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 17 May 2022 03:53:17 +0800 Subject: [PATCH 2/3] Remove the required `SubmitReviewForm.Type`, empty type (triggered by quick submit) means "comment" --- services/forms/repo_form.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 18cbac751cd7c..63dc13830eb7a 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -623,7 +623,7 @@ func (f *CodeCommentForm) Validate(req *http.Request, errs binding.Errors) bindi // SubmitReviewForm for submitting a finished code review type SubmitReviewForm struct { Content string - Type string `binding:"Required;In(approve,comment,reject)"` + Type string CommitID string Files []string } @@ -643,6 +643,8 @@ func (f SubmitReviewForm) ReviewType() models.ReviewType { return models.ReviewTypeComment case "reject": return models.ReviewTypeReject + case "": + return models.ReviewTypeComment // default to comment default: return models.ReviewTypeUnknown } From 91f23cd05aeac1a11901bef4439bc9b459d2ce91 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 17 May 2022 12:50:29 +0800 Subject: [PATCH 3/3] Merge duplicate code --- services/forms/repo_form.go | 4 ++-- templates/repo/diff/box.tmpl | 2 +- templates/repo/issue/view_content.tmpl | 2 +- templates/user/settings/keys_ssh.tmpl | 4 ++-- web_src/js/features/common-global.js | 29 ++++++++++++++++---------- web_src/js/features/comp/EasyMDE.js | 14 ++++--------- web_src/js/features/repo-wiki.js | 7 +------ 7 files changed, 29 insertions(+), 33 deletions(-) diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go index 63dc13830eb7a..2bcb91f8c3ffa 100644 --- a/services/forms/repo_form.go +++ b/services/forms/repo_form.go @@ -634,7 +634,7 @@ func (f *SubmitReviewForm) Validate(req *http.Request, errs binding.Errors) bind return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// ReviewType will return the corresponding reviewtype for type +// ReviewType will return the corresponding ReviewType for type func (f SubmitReviewForm) ReviewType() models.ReviewType { switch f.Type { case "approve": @@ -644,7 +644,7 @@ func (f SubmitReviewForm) ReviewType() models.ReviewType { case "reject": return models.ReviewTypeReject case "": - return models.ReviewTypeComment // default to comment + return models.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form default: return models.ReviewTypeUnknown } diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index bfac8c52e8857..01d43c7d78315 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -180,7 +180,7 @@ {{$.i18n.Tr "preview"}}
- +
{{$.i18n.Tr "loading"}} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 91af5160b6dc8..48acdc3e01cff 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -202,7 +202,7 @@
- +
{{$.i18n.Tr "loading"}} diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl index 5051780efe55b..25b2c8a43288f 100644 --- a/templates/user/settings/keys_ssh.tmpl +++ b/templates/user/settings/keys_ssh.tmpl @@ -20,7 +20,7 @@
- +
- +