Skip to content

Commit

Permalink
HOTFIX drafts/edit as new messages' body duplicated (#321)
Browse files Browse the repository at this point in the history
* fix: avoid content duplication when edit a draft
* fix: escape possible html tags in reply/forward heading
  • Loading branch information
gnekoz authored Mar 13, 2023
1 parent 9a2c714 commit 2de2dd4
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 37 deletions.
18 changes: 11 additions & 7 deletions src/store/editor-slice-utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Zextras <https://www.zextras.com>
* SPDX-FileCopyrightText: 2023 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
Expand All @@ -12,6 +12,7 @@ import {
} from '../carbonio-ui-commons/constants/participants';
import { convertHtmlToPlainText } from '../carbonio-ui-commons/utils/text/html';
import { LineType } from '../commons/utils';
import { htmlEncode } from '../commons/get-quoted-text-util';
import { composeMailBodyWithSignature, getSignatureValue } from '../helpers/signatures';
import {
EditorAttachmentFiles,
Expand Down Expand Up @@ -183,7 +184,7 @@ export function retrieveCC(
);

if (original.parent !== FOLDERS.SENT && !original.isSentByMe) {
const uniqueParticipants = reduce(
return reduce(
concat(toEmails, reducedCcEmails),
(acc: Participant[], v: Participant) => {
if (!(finalTo.filter((x) => x.address === v.address).length > 0))
Expand All @@ -192,7 +193,6 @@ export function retrieveCC(
},
[]
);
return uniqueParticipants;
}

return changeTypeOfParticipants(reducedCcEmails, ParticipantRole.CARBON_COPY);
Expand Down Expand Up @@ -276,17 +276,21 @@ export function generateReplyText(

const textToRetArray = [
`\n\n${LineType.PLAINTEXT_SEP}\n${labels.from} ${headingFrom}\n${labels.to} ${headingTo}\n`,
`<br /><br /><hr id="${LineType.HTML_SEP_ID}" ><div style="color: black; font-size: 12pt; font-family: tahoma, arial, helvetica, sans-serif;"><b>${labels.from}</b> ${headingFrom} <br /> <b>${labels.to}</b> ${headingTo} <br />`
`<br /><br /><hr id="${
LineType.HTML_SEP_ID
}" ><div style="color: black; font-size: 12pt; font-family: tahoma, arial, helvetica, sans-serif;"><b>${
labels.from
}</b> ${htmlEncode(headingFrom)} <br /> <b>${labels.to}</b> ${htmlEncode(headingTo)} <br />`
];

if (headingCc.length > 0) {
textToRetArray[1] += `<b>${labels.cc}</b> ${headingCc}<br />`;
textToRetArray[1] += `<b>${labels.cc}</b> ${htmlEncode(headingCc)}<br />`;
textToRetArray[0] += `${labels.cc} ${headingCc}\n`;
}

textToRetArray[1] += `<b>${labels.sent}</b> ${date} <br /> <b>${labels.subject}</b> ${
textToRetArray[1] += `<b>${labels.sent}</b> ${date} <br /> <b>${labels.subject}</b> ${htmlEncode(
mail.subject
} <br /><br />${extractBody(mail)[1]}</div>`;
)} <br /><br />${extractBody(mail)[1]}</div>`;

textToRetArray[0] += `${labels.sent} ${date}\n${labels.subject} ${mail.subject}\n\n${
extractBody(mail)[0]
Expand Down
98 changes: 68 additions & 30 deletions src/views/app/detail-panel/edit/parts/edit-view-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ import { StoreProvider } from '../../../../../store/redux';
import { getSignatureValue } from '../../../../../helpers/signatures';
import { convertHtmlToPlainText } from '../../../../../carbonio-ui-commons/utils/text/html';

/**
* Match the first string which is between a
* signature separator and either a quoted text
* delimiter or the end of the content
*/
const PLAINTEXT_SIGNATURE_REGEX = new RegExp(
`(?<=^${LineType.SIGNATURE_PRE_SEP}\\n)(((?!\\s${LineType.PLAINTEXT_SEP}$).)*)`,
'ms'
);

const FromItem = styled(Row)`
border-radius: 4px;
cursor: pointer;
Expand Down Expand Up @@ -90,6 +100,62 @@ type PropType = {
action: string | undefined;
editor: MailsEditor;
};

/**
* Replaces the signature in a HTML message body.
*
* @param body - HTML message body
* @param newSignature - content of the new signature
*/
const replaceSignatureOnHtmlBody = (body: string, newSignature: string): string => {
const doc = new DOMParser().parseFromString(body, 'text/html');

// Get the element which wraps the signature
const signatureWrappers = doc.getElementsByClassName(LineType.SIGNATURE_CLASS);

let signatureWrapper = null;

// Locate the separator
const separator = doc.getElementById(LineType.HTML_SEP_ID);

// Locate the first signature. If no wrapper is found then the unchanged mail body is returned
signatureWrapper = signatureWrappers.item(0);
if (signatureWrapper == null) {
return body;
}

/*
* If a separator is present it should be located after the signature
* (the content after the separator is quoted text which shouldn't be altered).
* Otherwise the original body content is returned
*/
if (
separator &&
signatureWrapper.compareDocumentPosition(separator) !== Node.DOCUMENT_POSITION_FOLLOWING
) {
return body;
}

signatureWrapper.innerHTML = newSignature;
return doc.documentElement.innerHTML;
};

/**
* Replaces the signature in a plain text message body
*
* @param body - plain text message body
* @param newSignature - signature content
*/
const replaceSignatureOnPlainTextBody = (body: string, newSignature: string): string => {
// If no eligible signature is found the original body is returned
if (!body.match(PLAINTEXT_SIGNATURE_REGEX)) {
return body;
}

// Replace the target signature
return body.replace(PLAINTEXT_SIGNATURE_REGEX, newSignature);
};

const EditViewHeader: FC<PropType> = ({
setShowRouteGuard,
setValue,
Expand Down Expand Up @@ -130,38 +196,10 @@ const EditViewHeader: FC<PropType> = ({
const changeSignature = (isNew: boolean, id = ''): void => {
const editorText = editor.text;
const signatureValue = id !== '' ? getSignatureValue(getUserAccount(), id) : '';
const htmlContent = isNew
? editorText[1].substring(
0,
editorText[1].indexOf(`<div class="${LineType.SIGNATURE_CLASS}">`) +
`<div class="${LineType.SIGNATURE_CLASS}">`.length
) +
signatureValue +
editorText[1].substring(editorText[1].length - 6)
: `${
editorText[1].substring(
0,
editorText[1].indexOf(`<div class="${LineType.SIGNATURE_CLASS}">`) +
`<div class="${LineType.SIGNATURE_CLASS}">`.length
) + signatureValue
}<br>${editorText[1].substring(editorText[1].indexOf(`<hr id="${LineType.HTML_SEP_ID}`))}`;
const plainSignatureValue =
signatureValue !== '' ? `\n${convertHtmlToPlainText(signatureValue)}\n\n` : '';
const plainContent = isNew
? editorText[0].substring(
0,
editorText[0].indexOf(`${LineType.SIGNATURE_PRE_SEP}`) +
`${LineType.SIGNATURE_PRE_SEP}`.length
) +
plainSignatureValue +
editorText[0].substring(editorText[0].length)
: editorText[0].substring(
0,
editorText[0].indexOf(`${LineType.SIGNATURE_PRE_SEP}`) +
`${LineType.SIGNATURE_PRE_SEP}`.length
) +
plainSignatureValue +
editorText[0].substring(editorText[0].indexOf(`${LineType.PLAINTEXT_SEP}`));
const htmlContent = replaceSignatureOnHtmlBody(editorText[1], signatureValue);
const plainContent = replaceSignatureOnPlainTextBody(editorText[0], plainSignatureValue);
updateEditorCb({
text: [plainContent, htmlContent]
});
Expand Down

0 comments on commit 2de2dd4

Please sign in to comment.