summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorNicolas Lempereur <nle@odoo.com>2018-05-03 14:02:04 +0200
committerNicolas Lempereur <nle@odoo.com>2018-05-09 12:35:40 +0200
commitb739e659400a223ec2b6d41ef57f27966edfe294 (patch)
tree68c5df5637dfd26720930482334e191bb5df947d /addons
parent14f59f4b780fa1e757cfce6a46c62c7a6b00d13e (diff)
[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
Diffstat (limited to 'addons')
-rw-r--r--addons/web_editor/static/src/js/backend.js2
-rw-r--r--addons/web_editor/static/src/js/transcoder.js32
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 = $('<span/>').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))) {