From b739e659400a223ec2b6d41ef57f27966edfe294 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Thu, 3 May 2018 14:02:04 +0200 Subject: [PATCH 01/31] [FIX] web_editor: optimize big mail transcoding The browser may throw an error when a big mail such as one with hundreds thousands of tags is being transformed to have a style more compatible with mail clients. The error would be: "Uncaught RangeError: Maximum call stack size exceeded" This happens in jquery because we hare too many nodes (there is an ongoing issue at https://github.com./jquery/sizzle/issues/403) so this commit replace that part by a DFS traversal over DOM nodes. There was also an issue that not having the option "style-inline" would still cause some style code to be ran albeit it was intended not to be solved in 55c7d2d5b00. opw-1841107 closes #24550 --- addons/web_editor/static/src/js/backend.js | 2 +- addons/web_editor/static/src/js/transcoder.js | 32 +++++++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/addons/web_editor/static/src/js/backend.js b/addons/web_editor/static/src/js/backend.js index 964ececa06b..1c5feb7a7d4 100644 --- a/addons/web_editor/static/src/js/backend.js +++ b/addons/web_editor/static/src/js/backend.js @@ -146,7 +146,7 @@ var FieldTextHtmlSimple = widget.extend({ this.$content.html(this.text_to_html(value)); if (this.get("effective_readonly")) { this.resize(); - } else { + } else if (this.options['style-inline']) { transcoder.style_to_class(this.$content); } if (this.$content.is(document.activeElement)) { diff --git a/addons/web_editor/static/src/js/transcoder.js b/addons/web_editor/static/src/js/transcoder.js index a5cf20575d4..aff3b3210f6 100644 --- a/addons/web_editor/static/src/js/transcoder.js +++ b/addons/web_editor/static/src/js/transcoder.js @@ -182,14 +182,34 @@ var img_to_font = function ($editable) { }); }; +/* + * Utility function to apply function over descendants elements + * + * This is needed until the following issue of jQuery is solved: + * https://github.com./jquery/sizzle/issues/403 + * + * @param {Element} node The root Element node + * @param {Function} func The function applied over descendants + */ +var applyOverDescendants = function (node, func) { + node = node.firstChild; + while (node) { + if (node.nodeType === 1) { + func(node); + applyOverDescendants(node, func); + } + node = node.nextSibling; + } +}; + // convert class into inline style to send by mail var class_to_style = function ($editable) { if (!rulesCache.length) { getMatchedCSSRules($editable[0]); } - $editable.find('*').each(function () { - var $target = $(this); - var css = getMatchedCSSRules(this); + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); var style = $target.attr("style") || ""; _.each(css, function (v,k) { if (!(new RegExp('(^|;)\s*' + k).test(style))) { @@ -209,9 +229,9 @@ var style_to_class = function ($editable) { var $c = $('').appendTo("body"); - $editable.find('*').each(function () { - var $target = $(this); - var css = getMatchedCSSRules(this); + applyOverDescendants($editable[0], function (node) { + var $target = $(node); + var css = getMatchedCSSRules(node); var style = ""; _.each(css, function (v,k) { if (!(new RegExp('(^|;)\s*' + k).test(style))) { From d595e3a258f5f1f45b0b3dcf4ab43fdfebc83d40 Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 8 May 2018 16:46:23 +0200 Subject: [PATCH 02/31] [FIX] tools: mail transcoding css space consistent The transcoding of a mail (transforming CSS into inline styles on the element nodes of the mail) used the form: property:value; So when a mail is saved, it would be eg. with `style="property:value;"` and when it is being edited "property:value" is removed if available via CSS stylesheet given the structure. But the sanitize_style (introduced in bfe7aafa7) adds an espace before the value (which is more pretty but was probably not choosen in transcoding to decrease size of mail): property: value; so the inline style would not be removed when editing possibly causing conflict with the editor. With this commit, the sanitize_style doesn't add a space. It could have been changed in transcoding but the code is already rather slow and we don't want to use a regex replace or two string replace instead of the current one string replace. opw-1841107 --- odoo/addons/base/tests/test_mail.py | 4 ++-- odoo/addons/base/tests/test_mail_examples.py | 2 +- odoo/tools/mail.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/odoo/addons/base/tests/test_mail.py b/odoo/addons/base/tests/test_mail.py index 795d6824886..b94ebf57183 100644 --- a/odoo/addons/base/tests/test_mail.py +++ b/odoo/addons/base/tests/test_mail.py @@ -115,7 +115,7 @@ class TestSanitizer(unittest.TestCase): test_data = [ ( 'Coin coin ', - ['background-color: red', 'Coin coin'], + ['background-color:red', 'Coin coin'], ['position', 'top', 'left'] ), ( """
youplaboum
""", - ['font-size: 30px', 'youplaboum'], + ['font-size:30px', 'youplaboum'], ['some-property', 'top', 'cheval'] ), ( 'Coincoin', diff --git a/odoo/addons/base/tests/test_mail_examples.py b/odoo/addons/base/tests/test_mail_examples.py index a83e668d940..fcd83524fc0 100644 --- a/odoo/addons/base/tests/test_mail_examples.py +++ b/odoo/addons/base/tests/test_mail_examples.py @@ -510,7 +510,7 @@ REMOVE_CLASS = """ """ REMOVE_CLASS_IN = [ - '
', + '
', 'An error occured in a modal and I will send you back the html to try opening one on your end'] REMOVE_CLASS_OUT = [ '