From 42f03152ea86eb01467d00ada17fed4ec7d8f7d1 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sat, 12 Jan 2019 20:43:23 +0100 Subject: [PATCH] Support for some pasted styles --- .../redactor2/plugins/WoltLabClean.js | 117 +++++++++++++++++- .../redactor2/plugins/WoltLabPaste.js | 2 + 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js index 74aeedfe31..214ad5fb45 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js @@ -225,7 +225,39 @@ $.Redactor.prototype.WoltLabClean = function() { elBySelAll('span', div, function (span) { if (span.classList.contains('redactor-selection-marker')) return; - if (!span.hasAttribute('style') || !span.style.length) { + if (span.hasAttribute('style') && span.style.length) { + // Split the styles into separate chunks. + var color = span.style.getPropertyValue('color'); + var fontFamily = span.style.getPropertyValue('font-family'); + var fontSize = span.style.getPropertyValue('font-size'); + + var activeStyles = (color ? 1 : 0) + (fontFamily ? 1 : 0) + (fontSize ? 1 : 0); + while (activeStyles > 1) { + var newSpan = elCreate('span'); + if (color) { + newSpan.style.setProperty('color', color, ''); + span.style.removeProperty('color'); + color = ''; + activeStyles--; + } + else if (fontFamily) { + newSpan.style.setProperty('font-family', fontFamily, ''); + span.style.removeProperty('font-family'); + fontFamily = ''; + activeStyles--; + } + else if (fontSize) { + newSpan.style.setProperty('font-size', fontSize, ''); + span.style.removeProperty('font-size'); + fontSize = ''; + activeStyles--; + } + + span.parentNode.insertBefore(newSpan, span); + newSpan.appendChild(span); + } + } + else { while (span.childNodes.length) { span.parentNode.insertBefore(span.childNodes[0], span); } @@ -524,6 +556,89 @@ $.Redactor.prototype.WoltLabClean = function() { return data; }).bind(this); + + var mpRemoveEmptyInlineTags = this.clean.removeEmptyInlineTags; + this.clean.removeEmptyInlineTags = (function(html) { + var tags = this.opts.inlineTags; + var $div = $("
").html($.parseHTML(html, document, true)); + var self = this; + + var $spans = $div.find('span'); + var $tags = $div.find(tags.join(',')); + + // WoltLab modification: Preserve the `style` attribute on `` elements. + $tags.filter(':not(span)').removeAttr('style'); + + $tags.each(function () { + var tagHtml = $(this).html(); + if (this.attributes.length === 0 && self.utils.isEmpty(tagHtml)) { + $(this).replaceWith(function () { + return $(this).contents(); + }); + } + }); + + $spans.each(function () { + var tagHtml = $(this).html(); + if (this.attributes.length === 0) { + $(this).replaceWith(function () { + return $(this).contents(); + }); + } + }); + + html = $div.html(); + + // convert php tags + html = html.replace('', '?>'); + + $div.remove(); + + return html; + }).bind(this); + }, + + removeRedundantStyles: function () { + var removeElements = []; + + // Remove tags that are always safe to remove. + var plainTags = [ + 'del', + 'em', + 'strong', + 'sub', + 'sup', + 'u' + ]; + elBySelAll(plainTags.join(','), this.$editor[0], function(element) { + if (elBySel(element.nodeName, element) !== null) { + removeElements.push(element); + } + }); + + // Search for span[style] that contain styles that actually do nothing, because their set style + // equals the inherited style from its ancestors. + elBySelAll('span[style]', this.$editor[0], function(element) { + ['color', 'font-family', 'font-size'].forEach(function(propertyName) { + var value = element.style.getPropertyValue(propertyName); + if (value) { + if (window.getComputedStyle(element.parentNode).getPropertyValue(propertyName) === value) { + removeElements.push(element); + } + } + }); + }); + + var parent; + removeElements.forEach(function(element) { + parent = element.parentNode; + while (element.childNodes.length) { + parent.insertBefore(element.childNodes[0], element); + } + parent.removeChild(element); + }); } } }; diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabPaste.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabPaste.js index 8371cfc8a9..4300e4546f 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabPaste.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabPaste.js @@ -399,6 +399,8 @@ $.Redactor.prototype.WoltLabPaste = function() { } badNodes.forEach(elRemove); + this.WoltLabClean.removeRedundantStyles(); + this.rtePaste = false; }).bind(this); -- 2.20.1