1 import LinkifyIt from 'linkify-it';
3 import { getUTMTrackersFromURL } from '@proton/shared/lib/mail/trackers';
4 import type { MessageUTMTracker } from '@proton/shared/lib/models/mailUtmTrackers';
6 const linkifyInstance = new LinkifyIt();
8 const htmlEntities = (str = '') => {
9 return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
13 * Convert plain text content with links to content with html links
14 * Input : `hello http://www.protonmail.com`
15 * Output : `hello <a target="_blank" rel="noreferrer nofollow noopener" href="http://protonmail.com">http://protonmail.com</a>`
17 export const transformLinkify = ({
20 rel = 'noreferrer nofollow noopener',
21 canCleanUTMTrackers = false,
27 canCleanUTMTrackers?: boolean;
28 onCleanUTMTrackers?: (utmTrackers: MessageUTMTracker[]) => void;
30 const matches = linkifyInstance.match(content);
33 return htmlEntities(content);
36 const utmTrackers: MessageUTMTracker[] = [];
38 const result = matches.reduce<string[]>((result, match) => {
39 if (last < match.index) {
40 result.push(htmlEntities(content.slice(last, match.index)));
42 result.push(`<a target="${target}" rel="${rel}" href="`);
44 const UTMTrackersResult = canCleanUTMTrackers ? getUTMTrackersFromURL(match.url) : undefined;
45 // Clean trackers in plaintext messages
46 if (UTMTrackersResult) {
47 result.push(UTMTrackersResult.url);
48 if (UTMTrackersResult.utmTracker) {
49 utmTrackers.push(UTMTrackersResult.utmTracker);
52 result.push(match.url);
56 result.push(match.text);
59 last = match.lastIndex;
64 // Push all trackers found to mail redux store
65 if (utmTrackers.length > 0) {
66 onCleanUTMTrackers?.(utmTrackers);
69 if (last < content.length) {
70 result.push(htmlEntities(content.slice(last)));
73 return result.join('');