From cf995791b02c13cd4714d8bfcb71e51559eecb49 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Thu, 29 May 2014 22:16:22 +0200 Subject: [PATCH] Fixed pasting of HTML, preserving visuals as best as possible --- com.woltlab.wcf/templates/wysiwyg.tpl | 1 + .../js/3rdParty/redactor/plugins/wbbcode.js | 76 +++++++++++++++++++ .../3rdParty/redactor/plugins/wmonkeypatch.js | 26 ++----- 3 files changed, 84 insertions(+), 19 deletions(-) diff --git a/com.woltlab.wcf/templates/wysiwyg.tpl b/com.woltlab.wcf/templates/wysiwyg.tpl index d8c30281ca..66b8b5b018 100644 --- a/com.woltlab.wcf/templates/wysiwyg.tpl +++ b/com.woltlab.wcf/templates/wysiwyg.tpl @@ -36,6 +36,7 @@ $(function() { var $config = { buttons: $buttons, minHeight: 200, + imageResizable: false, plugins: [ 'wutil', 'wmonkeypatch', 'wbutton', 'wbbcode', 'wfontcolor', 'wfontfamily', 'wfontsize' ], wautosave: { active: ($autosave) ? true : false, diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js index bedf4ea58e..cc615d8161 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wbbcode.js @@ -26,6 +26,9 @@ RedactorPlugins.wbbcode = { this.toggle(); } }, this); + + this.opts.pasteBeforeCallback = $.proxy(this._wPasteBeforeCallback, this); + this.opts.pasteAfterCallback = $.proxy(this._wPasteAfterCallback, this); }, /** @@ -142,6 +145,28 @@ RedactorPlugins.wbbcode = { html = html.replace(/
\n
\n/g, '');
 		html = html.replace(/<\/pre>\n
\n/g, ''); + html = html.replace(/
(?:\n
)+/g, function(match) { + var $count = match.match(/
/g); + return '@@@' + $count.length + '@@@'; + }); + html = html.replace(/\n@@@/g, '@@@'); + html = html.replace(/@@@(\d+)@@@/g, function(match, times) { + var $tmp = '
'; + for (var $i = 1; $i < times; $i++) { + $tmp += '\n
'; + } + + return $tmp; + }); + + // drop line break if there is a succeeding
+ /*html = html.replace(/(
)?\n
/g, function(match, br) { + console.debug("br was matched:"); + console.debug(match); + + return br ? match : '
'; + });*/ + // drop
, they are pointless because the editor already adds a newline after them html = html.replace(/
/g, ''); html = html.replace(/ /gi," "); @@ -519,5 +544,56 @@ RedactorPlugins.wbbcode = { data = data.replace(/\[code\][\S\s]*?\[\/code\]/, '
$&
'); this.$source.val(data); + }, + + /** + * Converts certain HTML elements prior to paste in order to preserve formattings. + * + * @param string html + * @return string + */ + _wPasteBeforeCallback: function(html) { + var $levels = { + 1: 24, + 2: 22, + 3: 18, + 4: 14, + 5: 12, + 6: 10 + }; + + // replace

...

tags + html = html.replace(/]+>/g, function(match, level) { + return '[size=' + $levels[level] + ']'; + }); + html = html.replace(/<\/h[1-6]>/g, '[/size]'); + + return html; + }, + + /** + * Restores and fixes formatting before inserting pasted HTML into the editor. + * + * @param string html + * @return string + */ + _wPasteAfterCallback: function(html) { + // restore font size + html = html.replace(/\[size=(\d+)\]/g, '

'); + html = html.replace(/\[\/size\]/g, '

'); + + // replace

with

...

+ html = html.replace(/

([\s\S]*?)<\/p>/g, '

$1

'); + + // drop
+ html = html.replace(/]*>/g, ''); + html = html.replace(/<\/header>/g, ''); + + html = html.replace(/
.*?<\/div>/g, '

$1

'); + + // drop lonely divs + html = html.replace(/<\/?div>/g, ''); + + return html; } }; diff --git a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js index 807cb949ed..6c36e361d6 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js +++ b/wcfsetup/install/files/js/3rdParty/redactor/plugins/wmonkeypatch.js @@ -23,8 +23,9 @@ RedactorPlugins.wmonkeypatch = { var $mpIndentingStart = this.indentingStart; this.indentingStart = function(cmd) { - $mpIndentingStart.call(self, cmd); - self.mpIndentingStart(cmd); + if (self.mpIndentingStart(cmd)) { + $mpIndentingStart.call(self, cmd); + } }; var $mpBuildEventKeydown = this.buildEventKeydown; @@ -50,11 +51,6 @@ RedactorPlugins.wmonkeypatch = { $mpModalInit.call(self, title, content, width, callback); }; - var $mpImageResizeControls = this.imageResizeControls; - this.imageResizeControls = function(image) { - return $mpImageResizeControls.call(self, image).hide(); - }; - this.setOption('modalOpenedCallback', $.proxy(this.modalOpenedCallback, this)); this.modalTemplatesInit(); @@ -98,19 +94,11 @@ RedactorPlugins.wmonkeypatch = { * @param string cmd */ mpIndentingStart: function(cmd) { - if (cmd === 'indent') { - var block = this.getBlock(); - if (block.tagName === 'DIV' && block.getAttribute('data-tagblock') !== null) { - this.selectionSave(); - - // drop the indention block again. bye bye block - block = $(block); - block.replaceWith(block.html()); - - this.selectionRestore(); - this.sync(); - } + if (this.getBlock().tagName == 'LI') { + return true; } + + return false; }, /** -- 2.20.1