From 50057c08aaf7817157962f44ecad5a69061fad99 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 11 Jan 2016 15:20:49 +0100 Subject: [FIX] web_editor: clean pasted dom and avoid crappy dom Chrome on windows add few comment tags and insert unwanted span. --- addons/web_editor/static/src/js/summernote.js | 135 +++----------------------- 1 file changed, 16 insertions(+), 119 deletions(-) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js index 14db16a831c..9f5ec3112f6 100644 --- a/addons/web_editor/static/src/js/summernote.js +++ b/addons/web_editor/static/src/js/summernote.js @@ -144,13 +144,13 @@ dom.mergeFilter = function (prev, cur, parent) { return true; } if (prev && !dom.isBR(prev) && dom.isEqual(prev, cur) && - ((prev.tagName && window.getComputedStyle(prev).display === "inline" && - cur.tagName && window.getComputedStyle(cur).display === "inline"))) { + ((prev.tagName && dom.getComputedStyle(prev).display === "inline" && + cur.tagName && dom.getComputedStyle(cur).display === "inline"))) { return true; } if (dom.isEqual(parent, cur) && - ((parent.tagName && window.getComputedStyle(parent).display === "inline" && - cur.tagName && window.getComputedStyle(cur).display === "inline"))) { + ((parent.tagName && dom.getComputedStyle(parent).display === "inline" && + cur.tagName && dom.getComputedStyle(cur).display === "inline"))) { return true; } if (parent && cur.tagName === "FONT" && (!cur.firstChild || (!cur.attributes.getNamedItem('style') && !cur.className.length))) { @@ -377,7 +377,7 @@ dom.removeSpace = function (node, begin, so, end, eo) { if (cur === begin) add = true; - if (cur.tagName && cur.tagName !== "SCRIPT" && cur.tagName !== "STYLE" && window.getComputedStyle(cur).whiteSpace !== "pre") { + if (cur.tagName && cur.tagName !== "SCRIPT" && cur.tagName !== "STYLE" && dom.getComputedStyle(cur).whiteSpace !== "pre") { __remove_space(cur); } @@ -592,7 +592,7 @@ dom.scrollIntoViewIfNeeded = function (node) { // get if a parent have a scrollbar parent = node.parentNode; while (parent != offsetParent && - (parent.tagName === "BODY" || ["auto", "scroll"].indexOf(window.getComputedStyle(parent).overflowY) === -1)) { + (parent.tagName === "BODY" || ["auto", "scroll"].indexOf(dom.getComputedStyle(parent).overflowY) === -1)) { parent = parent.parentNode; } node = parent; @@ -605,7 +605,7 @@ dom.scrollIntoViewIfNeeded = function (node) { offsetParent = node.offsetParent; } - if ((node.tagName === "BODY" || ["auto", "scroll"].indexOf(window.getComputedStyle(node).overflowY) !== -1) && + if ((node.tagName === "BODY" || ["auto", "scroll"].indexOf(dom.getComputedStyle(node).overflowY) !== -1) && (node.scrollTop + node.clientHeight) < (elY + elH)) { node.scrollTop = (elY + elH) - node.clientHeight; } @@ -710,7 +710,7 @@ dom.orderStyle = function (node) { * @return {String} className */ dom.orderClass = function (node) { - var className = node.getAttribute('class'); + var className = node.getAttribute && node.getAttribute('class'); if (!className) return null; className = className.replace(/[\s\n\r]+/, ' ').replace(/^ | $/g, '').replace(/ +/g, ' '); if (!className.length) { @@ -753,6 +753,11 @@ dom.moveContent = function (from, to) { } }; +dom.getComputedStyle = function (node) { + return node.nodeType == Node.COMMENT_NODE ? {} : window.getComputedStyle(node); +}; + + ////////////////////////////////////////////////////////////////////////////////////////////////////////// range.WrappedRange.prototype.reRange = function (keep_end, isNotBreakable) { @@ -1351,7 +1356,7 @@ $.summernote.pluginEvents.delete = function (event, editor, layoutInfo) { r = range.create(temp2, 0); r.select(); - if ((dom.isText(temp) || window.getComputedStyle(temp).display === "inline") && (dom.isText(temp2) || window.getComputedStyle(temp2).display === "inline")) { + if ((dom.isText(temp) || dom.getComputedStyle(temp).display === "inline") && (dom.isText(temp2) || dom.getComputedStyle(temp2).display === "inline")) { if (dom.isText(temp2)) { temp2.textContent = temp2.textContent.replace(/^\s*\S/, ''); } else { @@ -1498,7 +1503,7 @@ $.summernote.pluginEvents.backspace = function (event, editor, layoutInfo) { r = range.create(temp2, temp2.textContent.length, temp2, temp2.textContent.length); r.select(); - if ((dom.isText(temp) || window.getComputedStyle(temp).display === "inline") && (dom.isText(temp2) || window.getComputedStyle(temp2).display === "inline")) { + if ((dom.isText(temp) || dom.getComputedStyle(temp).display === "inline") && (dom.isText(temp2) || dom.getComputedStyle(temp2).display === "inline")) { if (dom.isText(temp2)) { temp2.textContent = temp2.textContent.replace(/\S\s*$/, ''); } else { @@ -2022,7 +2027,7 @@ $.summernote.pluginEvents.applyFont = function (event, editor, layoutInfo, color } if (size) { font.style.fontSize = "inherit"; - if (!isNaN(size) && Math.abs(parseInt(window.getComputedStyle(font).fontSize, 10)-size)/size > 0.05) { + if (!isNaN(size) && Math.abs(parseInt(dom.getComputedStyle(font).fontSize, 10)-size)/size > 0.05) { font.style.fontSize = size + "px"; } } @@ -2294,124 +2299,16 @@ eventHandler.modules.popover.update = function ($popover, oStyle, isAirMode) { ////////////////////////////////////////////////////////////////////////////////////////////////////////// -function summernote_paste (event) { - - // keep norma feature if copy a picture - var clipboardData = event.originalEvent.clipboardData; - if (!_.isEmpty(clipboardData.items)) { - var item = list.last(clipboardData.items); - var isClipboardImage = item.kind === 'file' && item.type.indexOf('image/') !== -1; - if (isClipboardImage) { - return true; - } - } - - if (["INPUT", "TEXTAREA"].indexOf(event.target.tagName) !== -1) { - return; - } - - $(event.target).trigger('content_changed'); - - var r = range.create(); - if (!r.isCollapsed()) { - r = r.deleteContents(); - r.select(); - } - - var html = clipboardData.getData("text/html"); - var $node = $('
').html(html); - // if copying source did not provide html, default to plain text - if(!html) { - $node.text(clipboardData.getData("text/plain")).html(function(_, html){ - return html.replace(/\r?\n/g,'
'); - }); - } - - /* - remove undesirable tag - filter classes and style attributes - remove undesirable attributes - */ - $node.find('meta, script, style').remove(); - $node.find('*').each(function() { - var $node = $(this); - - if ($node.attr('style')) { - var style = _.filter($node.attr('style').split(/\s*;\s*/), function (style) { - return /width|height|color|background-color|font-weight|text-align|font-style|text-decoration/i.test(style) && $node.css(style.split(':')[0]) !== $('body').css(style.split(':')[0]); - }).join(';'); - if (style.length) { - $node.attr('style', style); - } else { - $node.removeAttr('style'); - } - } - - if ($node.attr('class')) { - var classes = _.filter($node.attr('class').split(/\s+/), function (style) { - return /(^|\s)(fa|pull|text|bg)(\s|-|$)/.test(style); - }).join(' '); - if (classes.length) { - $node.attr('class', classes); - } else { - $node.removeAttr('class'); - } - } - }).removeAttr('title', 'alt', 'id', 'contenteditable'); - - /* - remove unless span - */ - $node.find('span:not([class]):not([style])').each(function () { - $(this).replaceWith($(this).contents()); - }); - $node.find('span + span').each(function () { - if ($(this).attr('class') === $(this).prev().attr('class') && $(this).attr('style') === $(this).prev().attr('style')) { - $(this).prev().append($(this).contents()); - $(this).remove(); - } - }); - - /* - reset architecture HTML node and add

tag - */ - var $arch = $('

'); - var $last = $arch.find('p'); - $node.contents().each(function () { - if (dom.isBR(this)) { - $(this).remove(); - $last = $('

'); - $arch.append($last); - } else if (/h[0-9]+|li|table|p/i.test(this.tagName)) { - $last = $('

'); - $arch.append(this).append($last); - } else { - $last.append(this); - } - }); - $last.filter(':empty').remove(); - - /* - insert content - */ - window.document.execCommand('insertHTML', false, $arch.html()); - - event.preventDefault(); - return false; -} - var fn_attach = eventHandler.attach; eventHandler.attach = function (oLayoutInfo, options) { var $editable = oLayoutInfo.editor().hasClass('note-editable') ? oLayoutInfo.editor() : oLayoutInfo.editor().find('.note-editable'); fn_attach.call(this, oLayoutInfo, options); - $(document).off("paste", summernote_paste).on("paste",'[contenteditable]', summernote_paste); $editable.on("scroll", summernote_table_scroll); }; var fn_detach = eventHandler.detach; eventHandler.detach = function (oLayoutInfo, options) { var $editable = oLayoutInfo.editor().hasClass('note-editable') ? oLayoutInfo.editor() : oLayoutInfo.editor().find('.note-editable'); fn_detach.call(this, oLayoutInfo, options); - $(document).off("paste", summernote_paste); $editable.off("scroll", summernote_table_scroll); $('.o_table_handler').remove(); }; -- cgit v1.2.3 From 0b2728d8b2e405ebbc52d544627bb3c16ec66d89 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Mon, 11 Jan 2016 15:23:36 +0100 Subject: [FIX] web_editor: error when long delete keypress in mass_mailing html issue: event does not a global var in firefox, and event is already prevented --- addons/web_editor/static/src/js/summernote.js | 1 - 1 file changed, 1 deletion(-) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/summernote.js b/addons/web_editor/static/src/js/summernote.js index 9f5ec3112f6..6ed7be2039f 100644 --- a/addons/web_editor/static/src/js/summernote.js +++ b/addons/web_editor/static/src/js/summernote.js @@ -1226,7 +1226,6 @@ function remove_table_content(r) { node.parentNode && !$(node.parentNode).hasClass('o_editable')); } } - event.preventDefault(); return false; } -- cgit v1.2.3 From cb79297a41b7747a9318fd4794dce422ee931060 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Tue, 12 Jan 2016 10:27:10 +0100 Subject: [FIX] web_editor: links edition (only website links) Commit f3f7bd9f240bc21dffadd784cdf77203b1a5148c adds an improvement which allows the user to edit links in an easier way. The problem is that it also allowed to edit... the edit buttons (example: the discard button). This commit moves the mentionned commit code below the code that checks if the target can be edited or not. --- addons/web_editor/static/src/js/rte.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'addons/web_editor/static/src') diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js index f50b93912ae..85721ba0387 100644 --- a/addons/web_editor/static/src/js/rte.js +++ b/addons/web_editor/static/src/js/rte.js @@ -508,6 +508,10 @@ var RTE = Widget.extend({ var $target = $(event.target); var $editable = $target.closest('.o_editable'); + if (!$editable.size()) { + return; + } + if ($target.is('a')) { $target.attr('contenteditable', true); setTimeout(function () { @@ -518,10 +522,6 @@ var RTE = Widget.extend({ $editable.attr('contenteditable', true); } - if (!$editable.size()) { - return; - } - if (this && this.$last && (!$editable.size() || this.$last[0] != $editable[0])) { var $destroy = this.$last; history.splitNext(); -- cgit v1.2.3