From 8a388f7f4325ce1ce83c794d4367bc42211732c9 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Sat, 4 Jul 2015 20:58:45 +0200 Subject: [PATCH] Added support for [tt] represented by --- com.woltlab.wcf/bbcode.xml | 4 +- .../js/3rdParty/redactor/plugins/wbbcode.js | 26 ++++++++ .../js/3rdParty/redactor/plugins/wbutton.js | 14 +++- .../3rdParty/redactor/plugins/wmonkeypatch.js | 65 +++++++++++++++---- .../js/3rdParty/redactor/plugins/wutil.js | 2 +- .../files/js/WoltLab/WCF/BBCode/FromHtml.js | 1 + .../files/js/WoltLab/WCF/BBCode/Parser.js | 41 ++++-------- .../files/js/WoltLab/WCF/BBCode/ToHtml.js | 3 + wcfsetup/install/files/style/bbcode.less | 1 + 9 files changed, 111 insertions(+), 46 deletions(-) diff --git a/com.woltlab.wcf/bbcode.xml b/com.woltlab.wcf/bbcode.xml index 5d0d51d2f7..302db0badc 100644 --- a/com.woltlab.wcf/bbcode.xml +++ b/com.woltlab.wcf/bbcode.xml @@ -162,8 +162,8 @@ wcf.bbcode.button.spoiler - code class="inlineCode" - code + kbd + kbd none 1 fa-terminal diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js index b66cd10bd7..9f9eb20a12 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js @@ -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 diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbutton.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbutton.js index 7f0df48288..a95d35ae97 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbutton.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbutton.js @@ -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 }); + $('
  • ').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 + ')'); } }, diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js index e196979d33..d83e38fcd8 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js @@ -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 + 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 diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wutil.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wutil.js index cd35245c5a..9167a77e22 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wutil.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wutil.js @@ -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); diff --git a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js index 4616e97ba4..71aefab413 100644 --- a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js +++ b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/FromHtml.js @@ -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) }, diff --git a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js index 2ea34d0f4e..0e3fb36054 100644 --- a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js +++ b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/Parser.js @@ -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) { diff --git a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js index 0eb669e996..ab11409b1f 100644 --- a/wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js +++ b/wcfsetup/install/files/js/WoltLab/WCF/BBCode/ToHtml.js @@ -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; diff --git a/wcfsetup/install/files/style/bbcode.less b/wcfsetup/install/files/style/bbcode.less index d87b9836bc..c47d49f0b0 100644 --- a/wcfsetup/install/files/style/bbcode.less +++ b/wcfsetup/install/files/style/bbcode.less @@ -389,6 +389,7 @@ html[dir='rtl'] { } /* inline code tag */ +kbd, .inlineCode { background-color: @wcfContentBackgroundColor; border: 1px solid @wcfContainerBorderColor; -- 2.20.1