From 55fa7238f26548f6b42c638e73e5be023cd5803c Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 2 Nov 2017 15:50:50 +0100 Subject: [PATCH] Improved `` behavior --- .../redactor2/plugins/WoltLabCaret.js | 54 +++++++++++++++++++ .../files/style/bbcode/inlineCode.scss | 35 ++++++++++-- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCaret.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCaret.js index 01b87d3dc3..8515169f9d 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCaret.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabCaret.js @@ -69,6 +69,7 @@ $.Redactor.prototype.WoltLabCaret = function() { }).bind(this); this.$editor[0].addEventListener(WCF_CLICK_EVENT, this.WoltLabCaret._handleEditorClick.bind(this)); + this.$editor[0].addEventListener('mouseup', this.WoltLabCaret._handleEditorMouseUp.bind(this)); this.WoltLabCaret._initInternalRange(); @@ -378,6 +379,59 @@ $.Redactor.prototype.WoltLabCaret = function() { this.caret.end(p); }, + _handleEditorMouseUp: function (event) { + var anchorNode, sibling; + + var selection = window.getSelection(); + if (!selection.isCollapsed) return; + + // click occured inside the editor padding + if (event.target === this.$editor[0]) { + anchorNode = selection.anchorNode; + if (anchorNode.nodeType === Node.TEXT_NODE) anchorNode = anchorNode.parentNode; + + // click occured before a `` element + if (anchorNode.nodeName === 'KBD') { + sibling = anchorNode.previousSibling; + if (sibling === null || sibling.textContent !== '\u200b') { + sibling = document.createTextNode('\u200b'); + anchorNode.parentNode.insertBefore(sibling, anchorNode); + } + + this.caret.before(sibling); + } + } + else if (event.target.nodeName === 'KBD') { + var kbd = event.target; + + // check if the user clicked on a `` element, but the browser placed the caret to the left + anchorNode = selection.anchorNode; + if (anchorNode.nodeType === Node.TEXT_NODE) { + // check if the first next sibling is the `` while skipping all empty text nodes + sibling = anchorNode; + while (sibling = sibling.nextSibling) { + if (sibling.nodeType !== Node.TEXT_NODE || (sibling.textContent !== '' && sibling.textContent !== '\u200b')) { + break; + } + } + + if (sibling === kbd) { + if (kbd.childNodes.length === 0 || kbd.childNodes[0].textContent !== '\u200b') { + var textNode = document.createTextNode('\u200b'); + kbd.insertBefore(textNode, kbd.firstChild); + } + + var range = document.createRange(); + range.setStartAfter(kbd.childNodes[0]); + range.setEndAfter(kbd.childNodes[0]); + + selection.removeAllRanges(); + selection.addRange(range); + } + } + } + }, + _addParagraphAfterBlock: function (block) { var nextElement = block.nextElementSibling; if (nextElement && (nextElement.nodeName === 'P' || this.utils.isBlockTag(nextElement.nodeName))) { diff --git a/wcfsetup/install/files/style/bbcode/inlineCode.scss b/wcfsetup/install/files/style/bbcode/inlineCode.scss index 2f158752e9..3be03a958a 100644 --- a/wcfsetup/install/files/style/bbcode/inlineCode.scss +++ b/wcfsetup/install/files/style/bbcode/inlineCode.scss @@ -1,17 +1,24 @@ .inlineCode, /* deprecated, legacy class */ kbd { + /* do not use inline-block, it breaks arrow key navigation in Firefox and Internet Explorer 11 */ + + /* update: `inline` styling breaks even more things, in particular the caret position is way off */ + /* this reverts 8d381dc61e8183adcb770457f9fba25c29c00bd2 */ + + /* new update: `display: inline` + `box-decoration-break` deliver the proper visual appearance, + and the `::after` element in the editor is used to fix the caret position at the end */ + background-color: rgba(255, 255, 255, 1) !important; border: 1px solid rgba(196, 196, 196, 1) !important; border-radius: 2px; + box-decoration-break: clone; + -webkit-box-decoration-break: clone; color: rgba(68, 68, 68, 1) !important; - /* do not use inline-block, it breaks arrow key navigation in Firefox and Internet Explorer 11 */ - /* update: `inline` styling breaks even more things, in particular the caret position is way off */ - /* this reverts 8d381dc61e8183adcb770457f9fba25c29c00bd2 */ - display: inline-block; + display: inline; font-family: Consolas, 'Courier New', monospace; font-style: normal; font-weight: normal; - margin: 1px 2px; + margin: 0 2px; overflow: auto; padding: 0 4px; text-decoration: none; @@ -19,3 +26,21 @@ kbd { word-break: break-all; word-wrap: break-word; } + +/* This pseudo element will cause a trailing caret to be displayed inside the element, right after + the last character in the ``. Without it, browsers may render the caret either on top or + slightly after the right border. */ +.redactor-layer kbd::after { + content: " "; + display: inline-block; + pointer-events: none; +} + +/* Similar to the `::after` pseudo element above, but also features an absolute positioning. This + has no impact on the visual appearance, but avoids the caret being displayed shifted to the bottom. */ +.redactor-layer kbd::before { + content: " "; + display: inline-block; + pointer-events: none; + position: absolute; +} -- 2.20.1