From 48aab263d1d60612be05a67c46172b5a5a718dba Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Tue, 4 Jan 2022 00:53:53 +0800 Subject: [PATCH] Fix EasyMDE validation (#18161) --- web_src/js/features/comp/CommentEasyMDE.js | 52 +++++++++++++--------- web_src/js/features/repo-diff.js | 2 +- web_src/js/features/repo-wiki.js | 14 +++--- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/web_src/js/features/comp/CommentEasyMDE.js b/web_src/js/features/comp/CommentEasyMDE.js index 8efbe4d34d..d3447d7ba2 100644 --- a/web_src/js/features/comp/CommentEasyMDE.js +++ b/web_src/js/features/comp/CommentEasyMDE.js @@ -75,13 +75,27 @@ export function createCommentEasyMDE(textarea) { } }); attachTribute(inputField, {mentions: true, emoji: true}); - - // TODO: that's the only way we can do now to attach the EasyMDE object to a HTMLElement - inputField._data_easyMDE = easyMDE; - textarea._data_easyMDE = easyMDE; + attachEasyMDEToElements(easyMDE); return easyMDE; } +/** + * attach the EasyMDE object to its input elements (InputField, TextArea) + * @param {EasyMDE} easyMDE + */ +export function attachEasyMDEToElements(easyMDE) { + // TODO: that's the only way we can do now to attach the EasyMDE object to a HTMLElement + + // InputField is used by CodeMirror to accept user input + const inputField = easyMDE.codemirror.getInputField(); + inputField._data_easyMDE = easyMDE; + + // TextArea is the real textarea element in the form + const textArea = easyMDE.codemirror.getTextArea(); + textArea._data_easyMDE = easyMDE; +} + + /** * get the attached EasyMDE editor created by createCommentEasyMDE * @param el jQuery or HTMLElement @@ -98,29 +112,27 @@ export function getAttachedEasyMDE(el) { } /** - * validate if the given textarea from a form, is non-empty. - * @param {jQuery | HTMLElement} form - * @param {jQuery | HTMLElement} textarea + * validate if the given EasyMDE textarea is is non-empty. + * @param {jQuery} $textarea * @returns {boolean} returns true if validation succeeded. */ -export function validateTextareaNonEmpty(form, textarea) { - if (form instanceof jQuery) { - form = form[0]; - } - if (textarea instanceof jQuery) { - textarea = textarea[0]; - } - - const $markdownEditorTextArea = $(getAttachedEasyMDE(textarea).codemirror.getInputField()); +export function validateTextareaNonEmpty($textarea) { + const $mdeInputField = $(getAttachedEasyMDE($textarea).codemirror.getInputField()); // The original edit area HTML element is hidden and replaced by the // SimpleMDE/EasyMDE editor, breaking HTML5 input validation if the text area is empty. // This is a workaround for this upstream bug. // See https://github.com/sparksuite/simplemde-markdown-editor/issues/324 - if (textarea.value.length) { - $markdownEditorTextArea.prop('required', true); - form.reportValidity(); + if (!$textarea.val()) { + $mdeInputField.prop('required', true); + const $form = $textarea.parents('form'); + if (!$form.length) { + // this should never happen. we put a alert here in case the textarea would be forgotten to be put in a form + alert('Require non-empty content'); + } else { + $form[0].reportValidity(); + } return false; } - $markdownEditorTextArea.prop('required', false); + $mdeInputField.prop('required', false); return true; } diff --git a/web_src/js/features/repo-diff.js b/web_src/js/features/repo-diff.js index d2502315b4..3378222ae1 100644 --- a/web_src/js/features/repo-diff.js +++ b/web_src/js/features/repo-diff.js @@ -27,7 +27,7 @@ export function initRepoDiffConversationForm() { const form = $(e.target); const $textArea = form.find('textarea'); - if (!validateTextareaNonEmpty(form, $textArea)) { + if (!validateTextareaNonEmpty($textArea)) { return; } diff --git a/web_src/js/features/repo-wiki.js b/web_src/js/features/repo-wiki.js index c7b902d31d..b76dac030e 100644 --- a/web_src/js/features/repo-wiki.js +++ b/web_src/js/features/repo-wiki.js @@ -1,5 +1,5 @@ import {initMarkupContent} from '../markup/content.js'; -import {validateTextareaNonEmpty} from './comp/CommentEasyMDE.js'; +import {attachEasyMDEToElements, validateTextareaNonEmpty} from './comp/CommentEasyMDE.js'; import {initCompMarkupContentPreviewTab} from './comp/MarkupContentPreview.js'; const {csrfToken} = window.config; @@ -119,11 +119,15 @@ export function initRepoWikiForm() { ] }); - const $markdownEditorTextArea = $(easyMDE.codemirror.getInputField()); - $markdownEditorTextArea.addClass('js-quick-submit'); + attachEasyMDEToElements(easyMDE); - $form.on('submit', function () { - validateTextareaNonEmpty(this, $editArea); + const $mdeInputField = $(easyMDE.codemirror.getInputField()); + $mdeInputField.addClass('js-quick-submit'); + + $form.on('submit', () => { + if (!validateTextareaNonEmpty($editArea)) { + return false; + } }); setTimeout(() => {