diff --git a/src/libs/actions/Report.js b/src/libs/actions/Report.js index f0977345cde..5ca0a465573 100644 --- a/src/libs/actions/Report.js +++ b/src/libs/actions/Report.js @@ -1162,17 +1162,16 @@ const removeLinksFromHtml = (html, links) => { * This function will handle removing only links that were purposely removed by the user while editing. * * @param {String} newCommentText text of the comment after editing. - * @param {String} originalHtml original html of the comment before editing. + * @param {String} originalCommentMarkdown original markdown of the comment before editing. * @returns {String} */ -const handleUserDeletedLinksInHtml = (newCommentText, originalHtml) => { +const handleUserDeletedLinksInHtml = (newCommentText, originalCommentMarkdown) => { const parser = new ExpensiMark(); if (newCommentText.length > CONST.MAX_MARKUP_LENGTH) { return newCommentText; } - const markdownOriginalComment = parser.htmlToMarkdown(originalHtml).trim(); const htmlForNewComment = parser.replace(newCommentText); - const removedLinks = parser.getRemovedMarkdownLinks(markdownOriginalComment, newCommentText); + const removedLinks = parser.getRemovedMarkdownLinks(originalCommentMarkdown, newCommentText); return removeLinksFromHtml(htmlForNewComment, removedLinks); }; @@ -1191,7 +1190,14 @@ function editReportComment(reportID, originalReportAction, textForNewComment) { // https://github.com/Expensify/App/issues/9090 // https://github.com/Expensify/App/issues/13221 const originalCommentHTML = lodashGet(originalReportAction, 'message[0].html'); - const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentHTML); + const originalCommentMarkdown = parser.htmlToMarkdown(originalCommentHTML).trim(); + + // Skip the Edit if draft is not changed + if (originalCommentMarkdown === textForNewComment) { + return; + } + + const htmlForNewComment = handleUserDeletedLinksInHtml(textForNewComment, originalCommentMarkdown); const reportComment = parser.htmlToText(htmlForNewComment); // For comments shorter than or equal to 10k chars, convert the comment from MD into HTML because that's how it is stored in the database @@ -1199,7 +1205,7 @@ function editReportComment(reportID, originalReportAction, textForNewComment) { let parsedOriginalCommentHTML = originalCommentHTML; if (textForNewComment.length <= CONST.MAX_MARKUP_LENGTH) { const autolinkFilter = {filterRules: _.filter(_.pluck(parser.rules, 'name'), (name) => name !== 'autolink')}; - parsedOriginalCommentHTML = parser.replace(parser.htmlToMarkdown(originalCommentHTML).trim(), autolinkFilter); + parsedOriginalCommentHTML = parser.replace(originalCommentMarkdown, autolinkFilter); } // Delete the comment if it's empty diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.js b/src/pages/PrivateNotes/PrivateNotesEditPage.js index 1bf99a6f568..b61e7bca7a7 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.js +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.js @@ -104,7 +104,7 @@ function PrivateNotesEditPage({route, personalDetailsList, session, report}) { const savePrivateNote = () => { const originalNote = lodashGet(report, ['privateNotes', route.params.accountID, 'note'], ''); - const editedNote = Report.handleUserDeletedLinksInHtml(privateNote.trim(), originalNote); + const editedNote = Report.handleUserDeletedLinksInHtml(privateNote.trim(), parser.htmlToMarkdown(originalNote).trim()); Report.updatePrivateNotes(report.reportID, route.params.accountID, editedNote); Keyboard.dismiss(); diff --git a/tests/actions/ReportTest.js b/tests/actions/ReportTest.js index 68a50fe4f13..025c226b3fb 100644 --- a/tests/actions/ReportTest.js +++ b/tests/actions/ReportTest.js @@ -428,33 +428,33 @@ describe('actions/Report', () => { // User edits comment to add link // We should generate link - let originalCommentHTML = 'Original Comment'; + let originalCommentMarkdown = 'Original Comment'; let afterEditCommentText = 'Original Comment www.google.com'; - let newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + let newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); let expectedOutput = 'Original Comment www.google.com'; expect(newCommentHTML).toBe(expectedOutput); // User deletes www.google.com link from comment but keeps link text // We should not generate link - originalCommentHTML = 'Comment www.google.com'; + originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com)'; afterEditCommentText = 'Comment www.google.com'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'Comment www.google.com'; expect(newCommentHTML).toBe(expectedOutput); // User Delete only () part of link but leaves the [] // We should not generate link - originalCommentHTML = 'Comment www.google.com'; + originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com)'; afterEditCommentText = 'Comment [www.google.com]'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'Comment [www.google.com]'; expect(newCommentHTML).toBe(expectedOutput); // User Generates multiple links in one edit // We should generate both links - originalCommentHTML = 'Comment'; + originalCommentMarkdown = 'Comment'; afterEditCommentText = 'Comment www.google.com www.facebook.com'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'Comment www.google.com ' + 'www.facebook.com'; @@ -462,41 +462,41 @@ describe('actions/Report', () => { // Comment has two links but user deletes only one of them // Should not generate link again for the deleted one - originalCommentHTML = 'Comment www.google.com www.facebook.com'; + originalCommentMarkdown = 'Comment [www.google.com](https://www.google.com) [www.facebook.com](https://www.facebook.com)'; afterEditCommentText = 'Comment www.google.com [www.facebook.com](https://www.facebook.com)'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'Comment www.google.com www.facebook.com'; expect(newCommentHTML).toBe(expectedOutput); // User edits and replaces comment with a link containing underscores // We should generate link - originalCommentHTML = 'Comment'; + originalCommentMarkdown = 'Comment'; afterEditCommentText = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; expect(newCommentHTML).toBe(expectedOutput); // User edits and deletes the link containing underscores // We should not generate link - originalCommentHTML = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; + originalCommentMarkdown = '[https://www.facebook.com/hashtag/__main/?__eep__=6](https://www.facebook.com/hashtag/__main/?__eep__=6)'; afterEditCommentText = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'https://www.facebook.com/hashtag/__main/?__eep__=6'; expect(newCommentHTML).toBe(expectedOutput); // User edits and replaces comment with a link containing asterisks // We should generate link - originalCommentHTML = 'Comment'; + originalCommentMarkdown = 'Comment'; afterEditCommentText = 'http://example.com/foo/*/bar/*/test.txt'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'http://example.com/foo/*/bar/*/test.txt'; expect(newCommentHTML).toBe(expectedOutput); // User edits and deletes the link containing asterisks // We should not generate link - originalCommentHTML = 'http://example.com/foo/*/bar/*/test.txt'; + originalCommentMarkdown = '[http://example.com/foo/*/bar/*/test.txt](http://example.com/foo/*/bar/*/test.txt)'; afterEditCommentText = 'http://example.com/foo/*/bar/*/test.txt'; - newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentHTML); + newCommentHTML = Report.handleUserDeletedLinksInHtml(afterEditCommentText, originalCommentMarkdown); expectedOutput = 'http://example.com/foo/*/bar/*/test.txt'; expect(newCommentHTML).toBe(expectedOutput); });