Improved inline format
authorAlexander Ebert <ebert@woltlab.com>
Tue, 6 Sep 2016 20:21:54 +0000 (22:21 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 6 Sep 2016 20:22:01 +0000 (22:22 +0200)
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
wcfsetup/install/files/js/WoltLabSuite/Core/Ui/Redactor/Format.js

index 6e93007fecd3dee937d524b402a53c40dabbb3d9..3e0a27b9b1e5a5524c3a908383727f95f7251498 100644 (file)
@@ -44,18 +44,26 @@ $.Redactor.prototype.WoltLabColor = function() {
                setColor: function(key) {
                        key = key.replace(/^color_/, '');
                        
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.format(this.$editor[0], 'woltlab-color', 'woltlab-color-' + key);
+                               
+                               this.buffer.set();
                        }).bind(this));
                },
                
                removeColor: function() {
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.removeFormat(this.$editor[0], 'woltlab-color');
+                               
+                               this.buffer.set();
                        }).bind(this));
                }
        };
index dcc216fdbd3134ed958632fb7f52bda2e3f9d2fc..55ab6f647f879aae576f3d7660f87ec1a1f45e01 100644 (file)
@@ -35,18 +35,26 @@ $.Redactor.prototype.WoltLabFont = function() {
                },
                
                setFont: function(key) {
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.format(this.$editor[0], 'woltlab-font', 'woltlab-font-' + key);
+                               
+                               this.buffer.set();
                        }).bind(this));
                },
                
                removeFont: function() {
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.removeFormat(this.$editor[0], 'woltlab-font');
+                               
+                               this.buffer.set();
                        }).bind(this));
                }
        };
index fd42c5c19e20cbc37990dac9be7a46df4185ad1a..d517e8fac3b52d5f2a94c8f29ba39bd6b5210e2f 100644 (file)
@@ -31,22 +31,29 @@ $.Redactor.prototype.WoltLabSize = function() {
                                        link.parentNode.classList.add('woltlab-size-selection');
                                }
                        });
-                       
                },
                
                setSize: function(key) {
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.format(this.$editor[0], 'woltlab-size', 'woltlab-size-' + key.replace(/^size_/, ''));
+                               
+                               this.buffer.set();
                        }).bind(this));
                },
                
                removeSize: function() {
+                       this.selection.save();
+                       
                        require(['WoltLabSuite/Core/Ui/Redactor/Format'], (function(UiRedactorFormat) {
                                this.buffer.set();
                                
                                UiRedactorFormat.removeFormat(this.$editor[0], 'woltlab-size');
+                               
+                               this.buffer.set();
                        }).bind(this));
                }
        };
index cbe27691873ec7b0721494aa432bed623822a4b1..0e2f77e800a4e7fafe8901d272deb5f6765fdeb8 100644 (file)
@@ -48,7 +48,7 @@ define(['Dom/Util'], function(DomUtil) {
                                document.execCommand('strikethrough');
                        }
                        
-                       var elements = elBySelAll('strike', editorElement), formatElement, property, strike;
+                       var elements = elBySelAll('strike', editorElement), formatElement, property, selectElements = [], strike;
                        for (var i = 0, length = elements.length; i < length; i++) {
                                strike = elements[i];
                                
@@ -63,6 +63,31 @@ define(['Dom/Util'], function(DomUtil) {
                                }
                                
                                DomUtil.replaceElement(strike, formatElement);
+                               selectElements.push(formatElement);
+                       }
+                       
+                       var count = selectElements.length;
+                       if (count) {
+                               var firstSelectedElement = selectElements[0];
+                               var lastSelectedElement = selectElements[count - 1];
+                               
+                               // check if parent is of the same format type
+                               // and contains only the selected nodes
+                               if (tmpElement === null && (firstSelectedElement.parentNode === lastSelectedElement.parentNode)) {
+                                       var parent = firstSelectedElement.parentNode;
+                                       if (parent.nodeName === tagName.toUpperCase()) {
+                                               if (this._isBoundaryElement(firstSelectedElement, parent, 'previous') && this._isBoundaryElement(lastSelectedElement, parent, 'next')) {
+                                                       DomUtil.unwrapChildNodes(parent);
+                                               }
+                                       }
+                               }
+                               
+                               range = document.createRange();
+                               range.setStart(firstSelectedElement, 0);
+                               range.setEnd(lastSelectedElement, lastSelectedElement.childNodes.length);
+                               
+                               selection.removeAllRanges();
+                               selection.addRange(range);
                        }
                },
                
@@ -209,7 +234,7 @@ define(['Dom/Util'], function(DomUtil) {
                        }
                        
                        // the strike element is now some kind of isolated, meaning we can now safely
-                       // remove all offending parent nodes without influcing formatting of any content
+                       // remove all offending parent nodes without influencing formatting of any content
                        // before or after the element
                        var elements = elByTag(tagName, lastMatchingParent);
                        while (elements.length) {
@@ -240,6 +265,28 @@ define(['Dom/Util'], function(DomUtil) {
                        }
                        
                        return match;
+               },
+               
+               /**
+                * Returns true if provided element is the first or last element
+                * of its parent, ignoring empty text nodes appearing between the
+                * element and the boundary.
+                * 
+                * @param       {Element}       element         target element
+                * @param       {Element}       parent          parent element
+                * @param       {string}        type            traversal direction, can be either `next` or `previous`
+                * @return      {boolean}       true if element is the non-empty boundary element
+                * @protected
+                */
+               _isBoundaryElement: function (element, parent, type) {
+                       var node = element;
+                       while (node = node[type + 'Sibling']) {
+                               if (node.nodeType !== Node.TEXT_NODE || node.textContent.replace(/\u200B/, '') !== '') {
+                                       return false;
+                               }
+                       }
+                       
+                       return true;
                }
        };
 });