Added support for [tt] represented by <kbd>
authorAlexander Ebert <ebert@woltlab.com>
Sat, 4 Jul 2015 18:58:45 +0000 (20:58 +0200)
committerAlexander Ebert <ebert@woltlab.com>
Sat, 4 Jul 2015 18:58:45 +0000 (20:58 +0200)
com.woltlab.wcf/bbcode.xml
wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js
wcfsetup/install/files/js/3rdParty/redactor/plugins/wbutton.js
wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js
wcfsetup/install/files/js/3rdParty/redactor/plugins/wutil.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js
wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js
wcfsetup/install/files/style/bbcode.less

index 5d0d51d2f7142eca983902bbca4cc2065a40106c..302db0badcf3f7bf810afe2326588d65a9b94afa 100644 (file)
                        <buttonlabel>wcf.bbcode.button.spoiler</buttonlabel>
                </bbcode>
                <bbcode name="tt">
-                       <htmlopen>code class="inlineCode"</htmlopen>
-                       <htmlclose>code</htmlclose>
+                       <htmlopen>kbd</htmlopen>
+                       <htmlclose>kbd</htmlclose>
                        <allowedchildren>none</allowedchildren>
                        <sourcecode>1</sourcecode>
                        <wysiwygicon>fa-terminal</wysiwygicon>
index b66cd10bd7bfb0fee9545c76550931943a09765a..9f9eb20a12e6058df20d568e5c7407ec1a90c9ab 100644 (file)
@@ -673,6 +673,7 @@ RedactorPlugins.wbbcode = function() {
                                case $.ui.keyCode.DOWN:
                                case $.ui.keyCode.ENTER:
                                case $.ui.keyCode.UP:
+                               case $.ui.keyCode.RIGHT:
                                case 83: // [S]
                                        // handle keys
                                break;
@@ -818,6 +819,9 @@ RedactorPlugins.wbbcode = function() {
                                                this.keydown.blockquote = false;
                                                this.keydown.enterWithinBlockquote = true;
                                        }
+                                       else if (current.nodeName === 'KBD') {
+                                               data.cancel = true;
+                                       }
                                break;
                                
                                // arrow up
@@ -857,6 +861,28 @@ RedactorPlugins.wbbcode = function() {
                                        data.cancel = true;
                                break;
                                
+                               case $.ui.keyCode.RIGHT:
+                                       var range = window.getSelection().getRangeAt(0);
+                                       if (range.startContainer.nodeType === Node.TEXT_NODE && range.startContainer.length === range.startOffset) {
+                                               current = current.parentNode;
+                                               if (current.nodeName !== 'KBD') {
+                                                       return;
+                                               }
+                                               
+                                               var editor = this.$editor[0];
+                                               if (current.nextElementSibling === editor.lastElementChild) {
+                                                       current = current.nextElementSibling;
+                                                       if (current.textContent === '') {
+                                                               current.textContent = '\u200b';
+                                                       }
+                                               }
+                                               
+                                               if (current === editor.lastElementChild) {
+                                                       this.wutil.selectionEndOfEditor();
+                                               }
+                                       }
+                               break;
+                               
                                // [S]
                                case 83:
                                        // not supported on mobile devices anyway
index 7f0df482887c1c95871afcbd8335f822627a07fd..a95d35ae973086190e7c8e3afd358f0afdf5b328 100644 (file)
@@ -129,8 +129,16 @@ RedactorPlugins.wbutton = function() {
                 */
                _addBBCodeButton: function(data) {
                        var $buttonName = '__wcf_' + data.name;
-                       var $button = this.button.add($buttonName, data.label);
-                       this.button.addCallback($button, this.wbutton._insertBBCode);
+                       var button = this.button.add($buttonName, data.label);
+                       if (data.name === 'tt') {
+                               var newButton = this.button.build($buttonName, { command: 'kbd', title: data.label });
+                               $('<li />').append(newButton).insertAfter(button.parent());
+                               button.parent().remove();
+                               button = newButton;
+                       }
+                       else {
+                               this.button.addCallback(button, this.wbutton._insertBBCode);
+                       }
                        
                        this._bbcodes[$buttonName] = {
                                name: data.name,
@@ -143,7 +151,7 @@ RedactorPlugins.wbutton = function() {
                        }
                        else {
                                // image reference
-                               $button.css('background-image', 'url(' + __REDACTOR_ICON_PATH + data.icon + ')');
+                               button.css('background-image', 'url(' + __REDACTOR_ICON_PATH + data.icon + ')');
                        }
                },
                
index e196979d335368d921538b6c7ffee405b003caed..d83e38fcd88150e5e06c88902b8aef29bab9207f 100644 (file)
@@ -154,12 +154,12 @@ RedactorPlugins.wmonkeypatch = function() {
                                }
                                else {
                                        ref = element.nextSibling;
-                                       if (ref === null) {
+                                       if (ref === null || ref === element.nextElementSibling && ref.nodeName === 'BR') {
                                                var space = this.utils.createSpaceElement();
                                                if (element.nextSibling === null) element.parentNode.appendChild(space);
                                                else element.parentNode.insertBefore(space, element.nextSibling);
                                                
-                                               this.caret.setEnd(space);
+                                               this.caret.setAfter(space);
                                        }
                                        else {
                                                this.caret.setBefore(ref);
@@ -212,6 +212,35 @@ RedactorPlugins.wmonkeypatch = function() {
                                                }
                                        }
                                        
+                                       // check if caret is now inside <kbd>
+                                       range = (window.getSelection().rangeCount) ? window.getSelection().getRangeAt(0) : null;
+                                       if (range !== null) {
+                                               var container = range.startContainer;
+                                               if (container.nodeType === Node.TEXT_NODE) container = container.parentNode;
+                                               
+                                               if (container.nodeName === 'KBD') {
+                                                       if (container.nextElementSibling === editor.lastElementChild) {
+                                                               if (editor.lastElementChild.nodeName === 'SPAN' && editor.lastElementChild.textContent === '') {
+                                                                       editor.removeChild(editor.lastElementChild);
+                                                               }
+                                                       }
+                                                       else if (container.nextSibling === container.nextElementSibling) {
+                                                               console.debug("this!");
+                                                               if (container.nextElementSibling.nodeName === 'KBD' || container.nextElementSibling.nodeName === 'BR') {
+                                                                       setCaretBeforeOrAfter(container, false);
+                                                               }
+                                                               else {
+                                                                       console.debug(container.nextSibling);
+                                                                       console.debug(container.nextElementSibling);
+                                                               }
+                                                       }
+                                                       
+                                                       if (container === editor.lastElementChild) {
+                                                               setCaretBeforeOrAfter(container, false);
+                                                       }
+                                               }
+                                       }
+                                       
                                        return false;
                                }
                                else if (event.target.nodeName === 'LI') {
@@ -238,7 +267,6 @@ RedactorPlugins.wmonkeypatch = function() {
                                        }
                                }
                                else if (event.target.nodeName === 'BLOCKQUOTE') {
-                                       range = (window.getSelection().rangeCount) ? window.getSelection().getRangeAt(0) : null;
                                        if (range !== null && range.collapsed) {
                                                // check if caret is now inside a quote
                                                var blockquote = null;
@@ -1064,9 +1092,9 @@ RedactorPlugins.wmonkeypatch = function() {
                 *  - handles custom button active states.
                 */
                observe: function() {
-                       var $toggleButtons = (function(parent, searchFor, buttonSelector, inverse, className, skipInSourceMode) {
+                       var $toggleButtons = (function(element, searchFor, buttonSelector, inverse, className, skipInSourceMode) {
                                var $buttons = this.$toolbar.find(buttonSelector);
-                               if (parent && parent.closest(searchFor, this.$editor[0]).length != 0) {
+                               if (element && element.closest(searchFor, this.$editor[0]).length != 0) {
                                        $buttons[(inverse ? 'removeClass' : 'addClass')](className);
                                }
                                else {
@@ -1083,14 +1111,27 @@ RedactorPlugins.wmonkeypatch = function() {
                        this.observe.buttons = (function(e, btnName) {
                                $mpButtons.call(this, e, btnName);
                                
-                               var parent = this.selection.getParent();
-                               parent = (parent === false) ? null : $(parent);
+                               var element = this.selection.getCurrent();
+                               if (element === false) {
+                                       console.debug("nope");
+                                       return;
+                               }
+                               
+                               if (element.nodeType === Node.TEXT_NODE) {
+                                       element = element.parentNode;
+                               }
+                               console.debug(element);
+                               if (element === this.$editor[0]) {
+                                       return;
+                               }
+                               
+                               element = $(element);
                                
-                               $toggleButtons(parent, 'ul, ol', 'a.re-indent, a.re-outdent', true, 'redactor-button-disabled');
-                               //$toggleButtons(parent, 'inline.inlineCode', 'a.re-__wcf_tt', false, 'redactor-act');
-                               $toggleButtons(parent, 'blockquote.quoteBox', 'a.re-__wcf_quote', false, 'redactor-button-disabled', true);
-                               $toggleButtons(parent, 'sub', 'a.re-subscript', false, 'redactor-act');
-                               $toggleButtons(parent, 'sup', 'a.re-superscript', false, 'redactor-act');
+                               $toggleButtons(element, 'ul, ol', 'a.re-indent, a.re-outdent', true, 'redactor-button-disabled');
+                               $toggleButtons(element, 'kbd', 'a.re-__wcf_tt', false, 'redactor-act');
+                               $toggleButtons(element, 'blockquote.quoteBox', 'a.re-__wcf_quote', false, 'redactor-button-disabled', true);
+                               $toggleButtons(element, 'sub', 'a.re-subscript', false, 'redactor-act');
+                               $toggleButtons(element, 'sup', 'a.re-superscript', false, 'redactor-act');
                        }).bind(this);
                        
                        // observe.load
index cd35245c5ae8f3e0666c3f6adbd42a3839eecb88..9167a77e22b28b2b07c6825ca772d1cf6c331b23 100644 (file)
@@ -717,7 +717,7 @@ RedactorPlugins.wutil = function() {
                 */
                selectionEndOfEditor: function() {
                        var lastChild = this.$editor[0].lastElementChild;
-                       if (lastChild === null || lastChild.nodeName === 'BLOCKQUOTE' || (lastChild.nodeName === 'DIV' && lastChild.classList.contains('codeBox'))) {
+                       if (lastChild === null || lastChild.nodeName === 'BLOCKQUOTE' || (lastChild.nodeName === 'DIV' && lastChild.classList.contains('codeBox')) || lastChild.nodeName === 'KBD') {
                                var element = this.utils.createSpaceElement();
                                this.$editor[0].appendChild(element);
                                
index 4616e97ba4fb4d1c8ec3f51ae07ed5e03c479c90..71aefab41308a5dfa8b405805758c567b0406bbb 100644 (file)
@@ -101,6 +101,7 @@ define(['EventHandler', 'StringUtil', 'DOM/Traverse'], function(EventHandler, St
                                { tagName: 'SUB', bbcode: 'sub' },
                                { tagName: 'SUP', bbcode: 'sup' },
                                { tagName: 'U', bbcode: 'u' },
+                               { tagName: 'KBD', bbcode: 'tt' },
                                
                                // callback replacement
                                { tagName: 'A', callback: this._convertUrl.bind(this) },
index 2ea34d0f4ec31bec59b295e69b44858262b4fc29..0e3fb360544c80c73843ea17fae141340a4b0c97 100644 (file)
@@ -63,33 +63,18 @@ define([], function() {
                                        }
                                        
                                        if (item.closing) {
-                                               var lastIndex = this._findOpenTag(openTags, item.name);
-                                               if (lastIndex === -1) {
-                                                       // tag was never opened, treat as plain text
-                                                       stack[i] = item.source;
+                                               if (this._hasOpenTag(openTags, item.name)) {
+                                                       reopenTags = this._closeUnclosedTags(stack, openTags, item.name);
+                                                       for (var j = 0, innerLength = reopenTags.length; j < innerLength; j++) {
+                                                               stack.splice(i, reopenTags[j]);
+                                                               i++;
+                                                       }
+                                                       
+                                                       openTags.pop().pair = i;
                                                }
                                                else {
-                                                       tag = openTags.pop();
-                                                       tag.pair = i;
-                                                       
-                                                       if (sourceBBCode === item.name) {
-                                                               // join previous items in the stack
-                                                               if (lastIndex + 2 < i) {
-                                                                       var joinWith = lastIndex + 1;
-                                                                       for (var j = lastIndex + 2; j < i; j++) {
-                                                                               stack[joinWith] += stack[j];
-                                                                               stack[j] = '';
-                                                                       }
-                                                               }
-                                                       }
-                                                       else {
-                                                               reopenTags = this._closeUnclosedTags(stack, openTags, item.name);
-                                                               
-                                                               for (var j = 0, innerLength = reopenTags.length; j < innerLength; j++) {
-                                                                       stack.splice(i, reopenTags[j]);
-                                                                       i++;
-                                                               }
-                                                       }
+                                                       // tag was never opened, treat as plain text
+                                                       stack[i] = item.source;
                                                }
                                                
                                                if (sourceBBCode === item.name) {
@@ -132,14 +117,14 @@ define([], function() {
                        return reopenTags.reverse();
                },
                
-               _findOpenTag: function(openTags, name) {
+               _hasOpenTag: function(openTags, name) {
                        for (var i = openTags.length - 1; i >= 0; i--) {
                                if (openTags[i].name === name) {
-                                       return i;
+                                       return true;
                                }
                        }
                        
-                       return -1;
+                       return false;
                },
                
                _parseAttributes: function(attrString) {
index 0eb669e99606036c171983bb0fa3effd9d4a3701..ab11409b1fd6f5dffff5c16b44d567ef2443d7d5 100644 (file)
@@ -59,6 +59,7 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                                table: 'table',
                                td: 'td',
                                tr: 'tr',
+                               tt: 'kbd',
                                
                                // callback replacement
                                color: this._replaceColor.bind(this),
@@ -85,6 +86,8 @@ define(['EventHandler', 'Language', 'StringUtil', 'WoltLab/WCF/BBCode/Parser'],
                        
                        if (replace === undefined) {
                                // treat as plain text
+                               console.debug(item);
+                               console.debug(stack);
                                stack[item.pair] = stack[item.pair].source;
                                
                                return item.source;
index d87b9836bc618dd1ce2116af801197f9ffc0f363..c47d49f0b0fce5b6b2b1f318e1fb249d03706235 100644 (file)
@@ -389,6 +389,7 @@ html[dir='rtl'] {
 }
 
 /* inline code tag */
+kbd,
 .inlineCode {
        background-color: @wcfContentBackgroundColor;
        border: 1px solid @wcfContainerBorderColor;