odoo.define('mail.utils', function (require) { "use strict"; var core = require('web.core'); var _t = core._t; /** * WARNING: this is not enough to unescape potential XSS contained in htmlString, transformFunction * should handle it or it should be handled after/before calling parseAndTransform. So if the result * of this function is used in a t-raw, be very careful. * * @param {string} htmlString * @param {function} transformFunction * @returns {string} */ function parseAndTransform(htmlString, transformFunction) { var openToken = "OPEN" + Date.now(); var string = htmlString.replace(/</g, openToken); var children; try { children = $('
' + string + '').contents(); } return _parseAndTransform(children, transformFunction) .replace(new RegExp(openToken, "g"), "<"); } /** * @param {Node[]} nodes * @param {function} transformFunction with: * param node * param function * return string * @return {string} */ function _parseAndTransform(nodes, transformFunction) { return _.map(nodes, function (node) { return transformFunction(node, function () { return _parseAndTransform(node.childNodes, transformFunction); }); }).join(""); } // Suggested URL Javascript regex of http://stackoverflow.com/questions/3809401/what-is-a-good-regular-expression-to-match-a-url // Adapted to make http(s):// not required if (and only if) www. is given. So `should.notmatch` does not match. // And further extended to include Latin-1 Supplement, Latin Extended-A, Latin Extended-B and Latin Extended Additional. var urlRegexp = /\b(?:https?:\/\/\d{1,3}(?:\.\d{1,3}){3}|(?:https?:\/\/|(?:www\.))[-a-z0-9@:%._+~#=\u00C0-\u024F\u1E00-\u1EFF]{2,256}\.[a-z]{2,13})\b(?:[-a-z0-9@:%_+.~#?&'$//=;\u00C0-\u024F\u1E00-\u1EFF]*)/gi; /** * @param {string} text * @param {Object} [attrs={}] * @return {string} linkified text */ function linkify(text, attrs) { attrs = attrs || {}; if (attrs.target === undefined) { attrs.target = '_blank'; } if (attrs.target === '_blank') { attrs.rel = 'noreferrer noopener'; } attrs = _.map(attrs, function (value, key) { return key + '="' + _.escape(value) + '"'; }).join(' '); return text.replace(urlRegexp, function (url) { var href = (!/^https?:\/\//i.test(url)) ? "http://" + url : url; return '' + url + ''; }); } function addLink(node, transformChildren) { if (node.nodeType === 3) { // text node const linkified = linkify(node.data); if (linkified !== node.data) { const div = document.createElement('div'); div.innerHTML = linkified; for (const childNode of [...div.childNodes]) { node.parentNode.insertBefore(childNode, node); } node.parentNode.removeChild(node); return linkified; } return node.textContent; } if (node.tagName === "A") return node.outerHTML; transformChildren(); return node.outerHTML; } /** * @param {string} htmlString * @return {string} */ function htmlToTextContentInline(htmlString) { const fragment = document.createDocumentFragment(); const div = document.createElement('div'); fragment.appendChild(div); htmlString = htmlString.replace(/
${htmlString}`;
}
return div
.textContent
.trim()
.replace(/[\n\r]/g, '')
.replace(/\s\s+/g, ' ');
}
function stripHTML(node, transformChildren) {
if (node.nodeType === 3) return node.data; // text node
if (node.tagName === "BR") return "\n";
return transformChildren();
}
function inline(node, transform_children) {
if (node.nodeType === 3) return node.data;
if (node.nodeType === 8) return "";
if (node.tagName === "BR") return " ";
if (node.tagName.match(/^(A|P|DIV|PRE|BLOCKQUOTE)$/)) return transform_children();
node.innerHTML = transform_children();
return node.outerHTML;
}
// Parses text to find email: Tagada -> [Tagada, address@mail.fr] or False
function parseEmail(text) {
if (text){
var result = text.match(/(.*)<(.*@.*)>/);
if (result) {
return [_.str.trim(result[1]), _.str.trim(result[2])];
}
result = text.match(/(.*@.*)/);
if (result) {
return [_.str.trim(result[1]), _.str.trim(result[1])];
}
return [text, false];
}
}
/**
* Returns an escaped conversion of a content.
*
* @param {string} content
* @returns {string}
*/
function escapeAndCompactTextContent(content) {
//Removing unwanted extra spaces from message
let value = owl.utils.escape(content).trim();
value = value.replace(/(\r|\n){2,}/g, ', )
// TDE note : should be done server-side, in Python -> use mail.compose.message ?
function getTextToHTML(text) {
return text
.replace(/((?:https?|ftp):\/\/[\S]+)/g,'$1 ')
.replace(/[\n\r]/g,'
');
}
function timeFromNow(date) {
if (moment().diff(date, 'seconds') < 45) {
return _t("now");
}
return date.fromNow();
}
return {
addLink: addLink,
getTextToHTML: getTextToHTML,
htmlToTextContentInline,
inline: inline,
linkify: linkify,
parseAndTransform: parseAndTransform,
parseEmail: parseEmail,
stripHTML: stripHTML,
timeFromNow: timeFromNow,
escapeAndCompactTextContent,
};
});