Fixed copy & paste stripping custom elements/format
authorAlexander Ebert <ebert@woltlab.com>
Fri, 16 Sep 2016 11:07:03 +0000 (13:07 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 16 Sep 2016 11:07:09 +0000 (13:07 +0200)
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabColor.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabFont.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabSize.js

index a3d17e5c59ce4f02b46a6dd7c7fa7e4040b371fa..373dcab82610b62df7cc6bf9cce427937343ba38 100644 (file)
@@ -73,6 +73,126 @@ $.Redactor.prototype.WoltLabClean = function() {
                                
                                return mpStripTags.call(this, input, denied);
                        }).bind(this);
+                       
+                       var mpOnPaste = this.clean.onPaste;
+                       this.clean.onPaste = (function (html, data, insert) {
+                               var div = elCreate('div');
+                               div.innerHTML = html;
+                               
+                               var element, elements = elBySelAll('[style]', div), property, removeStyles;
+                               for (var i = 0, length = elements.length; i < length; i++) {
+                                       element = elements[i];
+                                       
+                                       removeStyles = [];
+                                       for (var j = 0, innerLength = element.style.length; j < innerLength; j++) {
+                                               property = element.style[j];
+                                               
+                                               if (this.WoltLabClean._applyInlineStyle(element, property, element.style.getPropertyValue(property))) {
+                                                       removeStyles.push(property);
+                                               }
+                                       }
+                                       
+                                       removeStyles.forEach(function (property) {
+                                               element.style.removeProperty(property);
+                                       });
+                               }
+                               
+                               return mpOnPaste.call(this, div.innerHTML, data, insert);
+                       }).bind(this);
+                       
+                       var storage = [];
+                       var addToStorage = function (element, attributes) {
+                               var attrs = {};
+                               for (var i = 0, length = attributes.length; i < length; i++) {
+                                       attrs[attributes[i]] = elAttr(element, attributes[i]);
+                               }
+                               
+                               storage.push({
+                                       element: element,
+                                       attributes: attrs
+                               });
+                       };
+                       
+                       var mpConvertTags = this.clean.convertTags;
+                       this.clean.convertTags = (function(html, data) {
+                               var div = elCreate('div');
+                               div.innerHTML = html;
+                               
+                               // reset tag storage
+                               storage = [];
+                               
+                               WCF.System.Event.fireEvent('com.woltlab.wcf.redactor2', 'convertTags_' + this.$element[0].id, {
+                                       addToStorage: addToStorage,
+                                       div: div
+                               });
+                               
+                               storage.forEach(function (item, i) {
+                                       item.element.outerHTML = '###custom' + i + '###' + item.element.innerHTML + '###/custom' + i + '###';
+                               });
+                               
+                               return mpConvertTags.call(this, div.innerHTML, data);
+                       }).bind(this);
+                       
+                       var mpReconvertTags = this.clean.reconvertTags;
+                       this.clean.reconvertTags = (function(html, data) {
+                               if (storage.length) {
+                                       html = html.replace(/###(\/?)custom(\d+)###/g, '<$1woltlab-custom-tag data-index="$2">');
+                                       
+                                       var div = elCreate('div');
+                                       div.innerHTML = html;
+                                       
+                                       elBySelAll('woltlab-custom-tag', div, function (element) {
+                                               var index = ~~elData(element, 'index');
+                                               
+                                               if (storage[index]) {
+                                                       var itemData = storage[index];
+                                                       var newElement = elCreate(itemData.element.nodeName);
+                                                       for (var property in itemData.attributes) {
+                                                               if (itemData.attributes.hasOwnProperty(property)) {
+                                                                       elAttr(newElement, property, itemData.attributes[property]);
+                                                               }
+                                                       }
+                                                       
+                                                       element.parentNode.insertBefore(newElement, element);
+                                                       while (element.childNodes.length) {
+                                                               newElement.appendChild(element.childNodes[0]);
+                                                       }
+                                               }
+                                               
+                                               elRemove(element);
+                                       });
+                                       
+                                       html = div.innerHTML;
+                               }
+                               
+                               return mpReconvertTags.call(this, html, data);
+                       }).bind(this);
+               },
+               
+               _applyInlineStyle: function (element, property, value) {
+                       var className = '', tagName = '';
+                       
+                       switch (property) {
+                               case 'font-weight':
+                                       if (value == 600) {
+                                               if (element.closest('strong') === null) {
+                                                       tagName = 'strong';
+                                               }
+                                       }
+                                       break;
+                       }
+                       
+                       if (tagName) {
+                               var newElement = elCreate(tagName);
+                               if (className) newElement.className = className;
+                               
+                               element.parentNode.insertBefore(newElement, element);
+                               newElement.appendChild(element);
+                               
+                               return true;
+                       }
+                       
+                       return false;
                }
        }
 };
index 3e0a27b9b1e5a5524c3a908383727f95f7251498..6d0d75fd5cd266635038af49729bbd7f71c40311 100644 (file)
@@ -39,6 +39,15 @@ $.Redactor.prototype.WoltLabColor = function() {
                                }
                        });
                        
+                       WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'convertTags_' + this.$element[0].id, function (data) {
+                               elBySelAll('woltlab-color', data.div, function (element) {
+                                       if (element.className.match(/^woltlab-color-([0-9A-F]{6})$/)) {
+                                               if (colors.indexOf(RegExp.$1) !== -1) {
+                                                       data.addToStorage(element, ['class']);
+                                               }
+                                       }
+                               });
+                       });
                },
                
                setColor: function(key) {
index 55ab6f647f879aae576f3d7660f87ec1a1f45e01..b8c6fcc48cbadc5ee8dd95d0aa47d22042dd78ec 100644 (file)
@@ -32,6 +32,15 @@ $.Redactor.prototype.WoltLabFont = function() {
                                }
                        });
                        
+                       WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'convertTags_' + this.$element[0].id, function (data) {
+                               elBySelAll('woltlab-font', data.div, function (element) {
+                                       if (element.className.match(/^woltlab-font-([a-zA-Z]+)$/)) {
+                                               if (fonts.indexOf(RegExp.$1) !== -1) {
+                                                       data.addToStorage(element, ['class']);
+                                               }
+                                       }
+                               });
+                       });
                },
                
                setFont: function(key) {
index d517e8fac3b52d5f2a94c8f29ba39bd6b5210e2f..ac205792f619b1549d24ad317c0ffdb3004f72fc 100644 (file)
@@ -31,6 +31,16 @@ $.Redactor.prototype.WoltLabSize = function() {
                                        link.parentNode.classList.add('woltlab-size-selection');
                                }
                        });
+                       
+                       WCF.System.Event.addListener('com.woltlab.wcf.redactor2', 'convertTags_' + this.$element[0].id, function (data) {
+                               elBySelAll('woltlab-size', data.div, function (element) {
+                                       if (element.className.match(/^woltlab-size-(\d{1,2})$/)) {
+                                               if (sizes.indexOf(~~RegExp.$1) !== -1) {
+                                                       data.addToStorage(element, ['class']);
+                                               }
+                                       }
+                               });
+                       });
                },
                
                setSize: function(key) {