Resolved some performance issue on low-end devices
authorAlexander Ebert <ebert@woltlab.com>
Tue, 30 Aug 2016 20:52:17 +0000 (22:52 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 30 Aug 2016 20:52:23 +0000 (22:52 +0200)
com.woltlab.wcf/templates/wysiwyg.tpl
wcfsetup/install/files/acp/templates/wysiwyg.tpl
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabObserve.js [new file with mode: 0644]

index 0ce17eb9ed9988e5fc9b75915f8d5adea2e6d79e..fa3332ba7f9c688f3de0cd52e60f58a131364a68 100644 (file)
@@ -29,6 +29,7 @@
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMedia.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMention.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabModal.js?v={@LAST_UPDATE_TIME}',
+                       '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabObserve.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabPaste.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabQuote.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabReply.js?v={@LAST_UPDATE_TIME}',
                                        'WoltLabLink',
                                        'WoltLabList',
                                        'WoltLabModal',
+                                       'WoltLabObserve',
                                        'WoltLabPaste',
                                        'WoltLabQuote',
                                        'WoltLabReply',
index b8a52b2ad4dd5e4622530289c80dac40b49d6f43..fa3332ba7f9c688f3de0cd52e60f58a131364a68 100644 (file)
@@ -19,6 +19,7 @@
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabColor.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabDropdown.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabEvent.js?v={@LAST_UPDATE_TIME}',
+                       '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabFont.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabImage.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabInlineCode.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabInsert.js?v={@LAST_UPDATE_TIME}',
@@ -28,6 +29,7 @@
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMedia.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMention.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabModal.js?v={@LAST_UPDATE_TIME}',
+                       '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabObserve.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabPaste.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabQuote.js?v={@LAST_UPDATE_TIME}',
                        '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabReply.js?v={@LAST_UPDATE_TIME}',
                                                'insert-column-right': '{lang}wcf.editor.table.insertColumnRight{/lang}',
                                                'insert-row-above': '{lang}wcf.editor.table.insertRowAbove{/lang}',
                                                'insert-row-below': '{lang}wcf.editor.table.insertRowBelow{/lang}',
-
+                                               
                                                // size
                                                'remove-size': '{lang}wcf.editor.button.size.removeSize{/lang}',
-
+                                               
                                                // color
-                                               'remove-color': '{lang}wcf.editor.button.color.removeColor{/lang}'
+                                               'remove-color': '{lang}wcf.editor.button.color.removeColor{/lang}',
+                                               
+                                               // font
+                                               'remove-font': '{lang}wcf.editor.button.font.removeFont{/lang}'
                                        }
                                },
                                linkify: false,
                                        'WoltLabCode',
                                        'WoltLabColor',
                                        'WoltLabDropdown',
+                                       'WoltLabFont',
                                        'WoltLabImage',
                                        'WoltLabInlineCode',
                                        'WoltLabInsert',
                                        'WoltLabLink',
                                        'WoltLabList',
                                        'WoltLabModal',
+                                       'WoltLabObserve',
                                        'WoltLabPaste',
                                        'WoltLabQuote',
                                        'WoltLabReply',
diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabObserve.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabObserve.js
new file mode 100644 (file)
index 0000000..b677d1f
--- /dev/null
@@ -0,0 +1,135 @@
+$.Redactor.prototype.WoltLabCaret = function() {
+       "use strict";
+       
+       return {
+               init: function () {
+                       // These rewritten methods below are up to 5 times faster and help prevent
+                       // input lags on less powerful devices. Tests have shown that just using bold
+                       // text on an iPad 3rd Gen causes `observe.toolbar()` to take about 30ms
+                       // during each keystroke with spikes at 50ms, with the delay being up to 90
+                       // ms on backspace.
+                       // 
+                       // The same test with the new methods average at 9ms for regular keystrokes
+                       // and spiking at 20ms on backspace.
+                       
+                       var buttons = elByClass('re-button', this.button.toolbar()[0]);
+                       this.button.setInactiveAll = (function(key) {
+                               var button;
+                               for (var i = 0, length = buttons.length; i < length; i++) {
+                                       button = buttons[i];
+                                       if (button.classList.contains('re-' + key)) {
+                                               continue;
+                                       }
+                                       
+                                       button.classList.remove('redactor-act');
+                               }
+                       }).bind(this);
+                       
+                       this.observe.buttons = (function(e, btnName) {
+                               var current = this.selection.current();
+                               // WoltLab modification: parent is useless for us
+                               //var parent = this.selection.parent();
+                               
+                               if (e !== false)
+                               {
+                                       this.button.setInactiveAll();
+                               }
+                               else
+                               {
+                                       this.button.setInactiveAll(btnName);
+                               }
+                               
+                               if (e === false && btnName !== 'html')
+                               {
+                                       if ($.inArray(btnName, this.opts.activeButtons) !== -1)
+                                       {
+                                               this.button.toggleActive(btnName);
+                                       }
+                                       
+                                       return;
+                               }
+                               
+                               if (!this.utils.isRedactorParent(current))
+                               {
+                                       return;
+                               }
+                               
+                               // disable line
+                               if (this.utils.isCurrentOrParentHeader() || this.utils.isCurrentOrParent(['table', 'pre', 'blockquote', 'li']))
+                               {
+                                       this.button.disable('horizontalrule');
+                               }
+                               else
+                               {
+                                       this.button.enable('horizontalrule');
+                               }
+                               
+                               // WoltLab modification: we know that there will be quite a few
+                               // active button states, so we'll simply check all ancestors one
+                               // by one instead of searching the DOM over and over again
+                               var editor = this.$editor[0];
+                               if (current.nodeType !== Node.ELEMENT_NODE) current = current.parentNode;
+                               
+                               var tagName, tags = [];
+                               while (current !== editor) {
+                                       tagName = current.nodeName.toLowerCase();
+                                       if (tags.indexOf(tagName) === -1) {
+                                               if (this.opts.activeButtonsStates.hasOwnProperty(tagName)) {
+                                                       this.button.setActive(this.opts.activeButtonsStates[tagName]);
+                                               }
+                                               
+                                               // mark as known
+                                               tags.push(tagName);
+                                       }
+                                       
+                                       current = current.parentNode;
+                               }
+                               
+                       }).bind(this);
+                       
+                       this.observe.dropdowns = (function() {
+                               var current = this.selection.current();
+                               var editor = this.$editor[0];
+                               var isRedactor = this.utils.isRedactorParent(current);
+                               
+                               var tagName, tags = [];
+                               if (current && isRedactor) {
+                                       if (current.nodeType !== Node.ELEMENT_NODE) current = current.parentNode;
+                                       
+                                       while (current !== editor) {
+                                               tagName = current.nodeName.toLowerCase();
+                                               if (tags.indexOf(tagName) === -1) {
+                                                       tags.push(tagName);
+                                               }
+                                               
+                                               current = current.parentNode;
+                                       }
+                               }
+                               
+                               var finded = null;
+                               
+                               var value;
+                               for (var i = 0, length = this.opts.observe.dropdowns.length; i < length; i++) {
+                                       value = this.opts.observe.dropdowns[i];
+                                       
+                                       var observe = value.observe,
+                                           element = observe.element,
+                                           $item   = value.item,
+                                           inValues = (observe.in) ? observe.in : false,
+                                           outValues = (observe.out) ? observe.out : false;
+                                       
+                                       if (element === 'a' && finded === null) {
+                                               finded = $('<div />').html(this.selection.html()).find('a').length
+                                       }
+                                       
+                                       if ((tags.indexOf(element) !== -1 && isRedactor) || (element === 'a' && finded !== 0)) {
+                                               this.observe.setDropdownProperties($item, inValues, outValues);
+                                       }
+                                       else {
+                                               this.observe.setDropdownProperties($item, outValues, inValues);
+                                       }
+                               }
+                       }).bind(this);
+               }
+       };
+};