import { createElement, SettingsGet } from 'Common/Globals'; import { forEachObjectEntry, pInt } from 'Common/Utils'; import { proxy } from 'Common/Links'; const tpl = createElement('template'), htmlre = /[&<>"']/g, htmlmap = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }, replaceWithChildren = node => node.replaceWith(...[...node.childNodes]), // Strip tracking stripTracking = text => text .replace(/tracking\.(printabout\.nl[^?]+)\?.*/gsi, (...m) => m[1]) .replace(/^.+awstrack\.me\/.+(https:%2F%2F[^/]+)/gsi, (...m) => decodeURIComponent(m[1])) .replace(/([?&])utm_[a-z]+=[^&?#]*/gsi, '$1') .replace(/&&+/, ''); export const /** * @param {string} text * @returns {string} */ encodeHtml = text => (text && text.toString ? text.toString() : '' + text).replace(htmlre, m => htmlmap[m]), /** * Clears the Message Html for viewing * @param {string} text * @returns {string} */ cleanHtml = (html, oAttachments, removeColors) => { const debug = false, // Config()->Get('debug', 'enable', false); useProxy = !!SettingsGet('UseLocalProxyForExternalImages'), detectHiddenImages = true, // !!SettingsGet('try_to_detect_hidden_images'), result = { hasExternals: false }, findAttachmentByCid = cid => oAttachments.findByCid(cid), findLocationByCid = cid => { const attachment = findAttachmentByCid(cid); return attachment && attachment.contentLocation ? attachment : 0; }, // convert body attributes to CSS tasks = { link: value => { if (/^#[a-fA-Z0-9]{3,6}$/.test(value)) { tpl.content.querySelectorAll('a').forEach(node => node.style.color = value) } }, text: (value, node) => node.style.color = value, topmargin: (value, node) => node.style.marginTop = pInt(value) + 'px', leftmargin: (value, node) => node.style.marginLeft = pInt(value) + 'px', bottommargin: (value, node) => node.style.marginBottom = pInt(value) + 'px', rightmargin: (value, node) => node.style.marginRight = pInt(value) + 'px' }, allowedAttributes = [ // defaults 'name', 'dir', 'lang', 'style', 'title', 'background', 'bgcolor', 'alt', 'height', 'width', 'src', 'href', 'border', 'bordercolor', 'charset', 'direction', // a 'download', 'hreflang', // body 'alink', 'bottommargin', 'leftmargin', 'link', 'rightmargin', 'text', 'topmargin', 'vlink', // col 'align', 'valign', // font 'color', 'face', 'size', // hr 'noshade', // img 'hspace', 'sizes', 'srcset', 'vspace', // meter 'low', 'high', 'optimum', 'value', // ol 'reversed', 'start', // table 'cols', 'rows', 'frame', 'rules', 'summary', 'cellpadding', 'cellspacing', // th 'abbr', 'scope', // td 'colspan', 'rowspan', 'headers' ], disallowedTags = [ 'HEAD','STYLE','SVG','SCRIPT','TITLE','LINK','BASE','META', 'INPUT','OUTPUT','SELECT','BUTTON','TEXTAREA', 'BGSOUND','KEYGEN','SOURCE','OBJECT','EMBED','APPLET','IFRAME','FRAME','FRAMESET','VIDEO','AUDIO','AREA','MAP' ], nonEmptyTags = [ 'A','B','EM','I','SPAN','STRONG','O:P','TABLE' ]; tpl.innerHTML = html // .replace(/]*>[\s\S]*?<\/pre>/gi, pre => pre.replace(/\n/g, '\n
')) .replace(/]*>/gi, '') .replace(/<\?xml[^>]*\?>/gi, '') // Not supported by