Improved the paste results from MS Word
authorAlexander Ebert <ebert@woltlab.com>
Sun, 9 Feb 2020 14:17:33 +0000 (15:17 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 9 Feb 2020 14:17:33 +0000 (15:17 +0100)
Backport of b99034fb4bb799d0ca6f2aa46471b2221abadcfc

wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabClean.js
wcfsetup/install/files/js/3rdParty/redactor2/redactor.js

index b1b5ea9953d4b2a00b44fa5484dc0363bcc2aabc..658c3feb0c88a9fcd2de773afafab4635d57bfa1 100644 (file)
@@ -167,7 +167,11 @@ $.Redactor.prototype.WoltLabClean = function() {
                                        
                                        return WCF.String.escapeHTML(html);
                                }
-                               
+
+                               if (this.clean.isHtmlMsWord(html)) {
+                                       html = this.clean.cleanMsWord(html);
+                               }
+
                                var div = elCreate('div');
                                div.innerHTML = html.replace(/@@@WOLTLAB-P-ALIGN-(?:left|right|center|justify)@@@/g, '');
                                
index 232a598a2a3176597627fd575e95349e60b9c973..737bd1fdfd062dfd3eb4e328b9db3ecdc5506ccb 100644 (file)
                                html = html.replace(/<!--[\s\S]*?-->/g, "");
                                html = html.replace(/<o:p>[\s\S]*?<\/o:p>/gi, '');
                                        html = html.replace(/\n/g, " ");
-                                       html = html.replace(/<br\s?\/?>|<\/p>|<\/div>|<\/li>|<\/td>/gi, '\n\n');
+                                       html = html.replace(/<\/p>/gi, '</p><p><br data-redactor="br"></p>');
+                                       html = html.replace(/<\/div>|<\/li>|<\/td>/gi, '\n\n');
 
-                                       // lists
                                        var $div = $("<div/>").html(html);
 
+                                       // Find any <p> that contains a <br> and split it into separate paragraphs.
+                                       /** @var {Element} br */
+                                       elBySelAll('br', $div[0], function(br) {
+                                               if (elData(br, 'redactor') === 'br') {
+                                                       br.removeAttribute('data-redactor');
+                                               }
+                                               else {
+                                                       var parent = br.parentNode;
+                                                       if (parent && parent.nodeName === 'P') {
+                                                               var paragraph = elCreate('p');
+                                                               while (br.nextSibling) {
+                                                                       paragraph.appendChild(br.nextSibling);
+                                                               }
+                                                               parent.parentNode.insertBefore(paragraph, parent.nextSibling);
+                                                               elRemove(br);
+                                                       }
+                                               }
+                                       });
+
+                                       // lists
                                        var lastList = false;
                                        var lastLevel = 1;
                                        var listsIds = [];
                                        });
 
                                        $div.find('[data-level][data-list]').removeAttr('data-level data-list');
+
+                                       // Find lists at the top level that are surrounded by `<p><br></p>`.
+                                       elBySelAll('ol, ul', $div[0], function(list) {
+                                               ['nextElementSibling', 'previousElementSibling'].forEach(function(property) {
+                                                       var sibling = list[property];
+                                                       while (sibling && sibling.nodeName === 'P' && sibling.className === '') {
+                                                               if (sibling.innerHTML !== '<br>') {
+                                                                       break;
+                                                               }
+
+                                                               elRemove(sibling);
+                                                               sibling = list[property];
+                                                       }
+                                               });
+                                       });
+                                       
                                        html = $div.html();
 
                                        return html;