From d8761408cf17ecb0fcc57e60341b308034da7786 Mon Sep 17 00:00:00 2001 From: Alexander Ebert Date: Tue, 12 Jan 2016 23:57:11 +0100 Subject: [PATCH] Upgraded to Redactor II 1.2 --- com.woltlab.wcf/templates/wysiwyg.tpl | 1 + .../files/js/3rdParty/redactor2/redactor.js | 5265 ++++++++++++----- .../js/3rdParty/redactor2/redactor.min.js | 6 +- 3 files changed, 3710 insertions(+), 1562 deletions(-) diff --git a/com.woltlab.wcf/templates/wysiwyg.tpl b/com.woltlab.wcf/templates/wysiwyg.tpl index 2e08d1b1c6..ab2aea0de0 100644 --- a/com.woltlab.wcf/templates/wysiwyg.tpl +++ b/com.woltlab.wcf/templates/wysiwyg.tpl @@ -26,6 +26,7 @@ var config = { buttons: buttons, + minHeight: 200, plugins: ['WoltLabButton', 'WoltLabDropdown', 'WoltLabEvent', 'WoltLabQuote'], woltlab: { autosave: autosave diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js index db8ebbf60e..3b663f78f2 100644 --- a/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js +++ b/wcfsetup/install/files/js/3rdParty/redactor2/redactor.js @@ -1,7 +1,7 @@ /* Redactor II - Version 1.0.1 - Updated: October 13, 2015 + Version 1.2.0 + Updated: December 16, 2015 http://imperavi.com/redactor/ @@ -29,7 +29,6 @@ var uuid = 0; - // Plugin $.fn.redactor = function(options) { @@ -102,16 +101,20 @@ // Options $.Redactor = Redactor; - $.Redactor.VERSION = '1.0.1'; - $.Redactor.modules = ['air', 'autosave', 'block', 'browser', 'buffer', 'build', 'button', 'caret', 'clean', 'code', 'core', 'dropdown', + $.Redactor.VERSION = '1.2.0'; + $.Redactor.modules = ['air', 'autosave', 'block', 'buffer', 'build', 'button', 'caret', 'clean', 'code', 'core', 'detect', 'dropdown', 'events', 'file', 'focus', 'image', 'indent', 'inline', 'insert', 'keydown', 'keyup', - 'lang', 'line', 'link', 'linkify', 'list', 'modal', 'observe', 'paragraphize', 'paste', 'placeholder', - 'progress', 'selection', 'shortcuts', 'toolbar', 'upload', 'uploads3', 'utils']; + 'lang', 'line', 'link', 'linkify', 'list', 'marker', 'modal', 'observe', 'offset', 'paragraphize', 'paste', 'placeholder', + 'progress', 'selection', 'shortcuts', 'storage', 'toolbar', 'upload', 'uploads3', 'utils', + + 'browser' // deprecated + ]; $.Redactor.settings = {}; $.Redactor.opts = { // settings + animation: false, lang: 'en', direction: 'ltr', @@ -136,6 +139,12 @@ linkify: true, enterKey: true, + pastePlainText: false, + pasteImages: true, + pasteLinks: true, + pasteBlockTags: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'table', 'tbody', 'thead', 'tfoot', 'th', 'tr', 'td', 'ul', 'ol', 'li', 'blockquote', 'pre'], + pasteInlineTags: ['strong', 'b', 'u', 'em', 'i', 'code', 'del', 'ins', 'samp', 'kbd', 'sup', 'sub', 'mark', 'var', 'cite', 'small'], + preClass: false, // string preSpaces: 4, // or false tabAsSpaces: false, // true or number of spaces @@ -147,28 +156,37 @@ imageUpload: null, imageUploadParam: 'file', + imageUploadFields: false, + imageUploadForms: false, + + imageCaption: true, + dragImageUpload: true, + multipleImageUpload: true, + clipboardImageUpload: true, fileUpload: null, fileUploadParam: 'file', + fileUploadFields: false, + fileUploadForms: false, dragFileUpload: true, s3: false, linkTooltip: true, - linkProtocol: 'http', linkNofollow: false, - linkSize: 50, + linkSize: 30, + + videoContainerClass: 'video-container', toolbar: true, toolbarFixed: true, toolbarFixedTarget: document, toolbarFixedTopOffset: 0, // pixels toolbarExternal: false, // ID selector - toolbarOverflow: false, - toolbarCustom: false, air: false, + airWidth: false, formatting: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], formattingAdd: false, @@ -193,6 +211,16 @@ }, shortcutsAdd: false, + activeButtons: ['deleted', 'italic', 'bold'], + activeButtonsStates: { + b: 'bold', + strong: 'bold', + i: 'italic', + em: 'italic', + del: 'deleted', + strike: 'deleted' + }, + // private lang langs: { en: { @@ -239,6 +267,7 @@ "indent": "Indent", "horizontalrule": "Line", "upload-label": "Drop file here or ", + "caption": "Caption", "accessibility-help-label": "Rich text editor" } @@ -328,6 +357,12 @@ // extend shortcuts $.extend(this.opts.shortcuts, this.opts.shortcutsAdd); + // set editor + this.$editor = this.$element; + + // detect type of editor + this.detectType(); + // start callback this.core.callback('start'); this.core.callback('startToEdit'); @@ -337,6 +372,21 @@ this.build.start(); }, + detectType: function() + { + if (this.build.isInline() || this.opts.inline) + { + this.opts.type = 'inline'; + } + else if (this.build.isTag('DIV')) + { + this.opts.type = 'div'; + } + else if (this.build.isTag('PRE')) + { + this.opts.type = 'pre'; + } + }, loadToEdit: function(options) { @@ -355,7 +405,7 @@ $.extend(options.callbacks, { startToEdit: function() { - this.insert.node(this.selection.marker(), false); + this.insert.node(this.marker.get(), false); }, initToEdit: function() { @@ -363,6 +413,7 @@ this.clickToCancelStorage = this.code.get(); // cancel + $(this.opts.clickToCancel).off('.redactor-click-to-edit'); $(this.opts.clickToCancel).show().on('click.redactor-click-to-edit', $.proxy(function(e) { e.preventDefault(); @@ -375,15 +426,18 @@ this.clickToCancelStorage = ''; $(this.opts.clickToCancel).hide(); $(this.opts.clickToSave).hide(); + this.$element.on('click.redactor-click-to-edit', $.proxy(function() { this.initToEdit(options); }, this)); + this.$element.addClass('redactor-click-to-edit'); }, this)); // save + $(this.opts.clickToSave).off('.redactor-click-to-edit'); $(this.opts.clickToSave).show().on('click.redactor-click-to-edit', $.proxy(function(e) { e.preventDefault(); @@ -404,15 +458,30 @@ }); this.$element.redactor(options); - this.$element.off('click.redactor-click-to-edit'); + this.$element.off('.redactor-click-to-edit'); }, loadOptions: function(options) { + var settings = {}; + + // check namespace + if (typeof $.Redactor.settings.namespace !== 'undefined') + { + if (this.$element.hasClass($.Redactor.settings.namespace)) + { + settings = $.Redactor.settings; + } + } + else + { + settings = $.Redactor.settings; + } + this.opts = $.extend( {}, $.extend(true, {}, $.Redactor.opts), - $.extend(true, {}, $.Redactor.settings), + $.extend(true, {}, settings), this.$element.data(), options ); @@ -473,7 +542,7 @@ }, build: function() { - if (this.utils.isMobile()) + if (this.detect.isMobile()) { return; } @@ -488,6 +557,11 @@ this.$air = this.air.createContainer(); + if (this.opts.airWidth !== false) + { + this.$air.css('width', this.opts.airWidth); + } + this.air.append(); this.button.$toolbar = this.$air; this.button.setFormatting(); @@ -513,7 +587,7 @@ }, show: function (e) { - this.selection.removeMarkers(); + this.marker.remove(); this.selection.save(); this.selection.restore(false); @@ -546,7 +620,7 @@ var hide = this.air.hide(e); if (hide !== false) { - this.selection.removeMarkers(); + this.marker.remove(); } } @@ -561,19 +635,19 @@ if (key === this.keyCode.ESC) { this.selection.get().collapseToStart(); - this.selection.removeMarkers(); + this.marker.remove(); } else if (key === this.keyCode.BACKSPACE || key === this.keyCode.DELETE) { var sel = this.selection.get(); var range = this.selection.range(sel); range.deleteContents(); - this.selection.removeMarkers(); + this.marker.remove(); } else if (key === this.keyCode.ENTER) { this.selection.get().collapseToEnd(); - this.selection.removeMarkers(); + this.marker.remove(); } if (this.air.enabled) @@ -583,7 +657,7 @@ else { this.selection.get().collapseToStart(); - this.selection.removeMarkers(); + this.marker.remove(); } @@ -724,13 +798,19 @@ { tag = (tag === 'quote') ? 'blockquote' : tag; - this.block.tags = ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div']; + this.block.tags = ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'div', 'figure']; if ($.inArray(tag, this.block.tags) === -1) { return; } - this.placeholder.remove(); + if (tag === 'p' && typeof attr === 'undefined') + { + // remove all + attr = 'class'; + } + + this.placeholder.hide(); this.buffer.set(); return (this.utils.isCollapsed()) ? this.block.formatCollapsed(tag, attr, value, type) : this.block.formatUncollapsed(tag, attr, value, type); @@ -767,6 +847,14 @@ replaced = this.block.setAttr(replaced, attr, value, type); } + + // trim pre + if (tag === 'pre' && replaced.length === 1) + { + $(replaced).html($.trim($(replaced).html())); + } + + this.selection.restore(); this.block.removeInlineTags(replaced); @@ -807,6 +895,23 @@ this.selection.restore(); + // combine pre + if (tag === 'pre' && replaced.length !== 0) + { + var first = replaced[0]; + $.each(replaced, function(i,s) + { + if (i !== 0) + { + $(first).append("\n" + $.trim(s.html())); + $(s).remove(); + } + }); + + replaced = []; + replaced.push(first); + } + return replaced; }, removeInlineTags: function(node) @@ -948,31 +1053,6 @@ }; }, - // =browser - browser: function() - { - return { - webkit: function() - { - return /webkit/.test(this.opts.userAgent); - }, - ff: function() - { - return this.opts.userAgent.indexOf('firefox') > -1; - }, - ie: function(v) - { - var ie; - ie = RegExp('msie' + (!isNaN(v)?('\\s'+v):''), 'i').test(navigator.userAgent); - if (!ie) - { - ie = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./); - } - return ie; - } - }; - }, - // buffer buffer: function() { @@ -991,7 +1071,14 @@ setUndo: function() { this.selection.save(); - this.opts.buffer.push(this.core.editor().html()); + + var last = this.opts.buffer[this.opts.buffer.length-1]; + var current = this.core.editor().html(); + if (last !== current) + { + this.opts.buffer.push(current); + } + this.selection.restore(); }, setRedo: function() @@ -1002,17 +1089,11 @@ }, getUndo: function() { - this.events.stopDetect(); this.core.editor().html(this.opts.buffer.pop()); - this.events.startDetect(); - }, getRedo: function() { - this.events.stopDetect(); this.core.editor().html(this.opts.rebuffer.pop()); - this.events.startDetect(); - }, add: function() { @@ -1029,8 +1110,6 @@ this.buffer.getUndo(); this.selection.restore(); - - setTimeout($.proxy(this.observe.load, this), 50); }, redo: function() { @@ -1043,8 +1122,6 @@ this.buffer.getRedo(); this.selection.restore(); - - setTimeout($.proxy(this.observe.load, this), 50); } }; }, @@ -1055,31 +1132,20 @@ return { start: function() { - this.$editor = this.$element; - - // load - if (this.build.isInline() || this.opts.inline) + if (this.opts.type === 'inline') { this.opts.type = 'inline'; - this.opts.inline = true; - this.opts.linkify = false; } - else if (this.build.isTag('DIV')) + else if (this.opts.type === 'div') { - this.opts.type = 'div'; - // empty - if (this.$editor.html() === '') + var html = $.trim(this.$editor.html()); + if (html === '') { this.$editor.html(this.opts.emptyHtml); } - } - else if (this.build.isTag('PRE')) - { - this.opts.type = 'pre'; - } - else + else if (this.opts.type === 'textarea') { this.build.startTextarea(); } @@ -1206,6 +1272,10 @@ { this.core.editor().css('min-height', this.opts.minHeight); } + else + { + this.core.editor().css('min-height', '40px'); + } // max height if (this.opts.maxHeight) @@ -1234,12 +1304,6 @@ this.toolbarsButtons = this.button.init(); } - // custom toolbar - if (this.opts.toolbarCustom) - { - this.toolbar.custom(); - } - // load toolbar if (this.opts.air) { @@ -1250,7 +1314,7 @@ this.toolbar.build(); } - if (this.utils.isMobile() && this.opts.toolbarMobile && this.opts.air) + if (this.detect.isMobile() && this.opts.toolbarMobile && this.opts.air) { this.opts.toolbar = true; this.toolbar.build(); @@ -1259,7 +1323,12 @@ // observe dropdowns if (this.opts.air || this.opts.toolbar) { - this.core.editor().on('mouseup.redactor keyup.redactor focus.redactor', $.proxy(this.observe.dropdowns, this)); + this.core.editor().on('mouseup.redactor-observe.' + this.uuid + ' keyup.redactor-observe.' + this.uuid + ' focus.redactor-observe.' + this.uuid + ' touchstart.redactor-observe.' + this.uuid, $.proxy(this.observe.toolbar, this)); + this.core.element().on('blur.callback.redactor', $.proxy(function() + { + this.button.setInactiveAll(); + + }, this)); } // modal templates init @@ -1274,13 +1343,13 @@ // sync code this.code.html = this.code.cleaned(this.core.editor().html()); - // observers - setTimeout($.proxy(this.observe.load, this), 4); - // init callback this.core.callback('init'); this.core.callback('initToEdit'); + // get images & files list + this.storage.observe(); + // started this.start = false; @@ -1294,7 +1363,7 @@ } // placeholder - this.placeholder.enable(); + this.placeholder.init(); // focus if (this.opts.focus) @@ -1587,7 +1656,7 @@ }, hideButtonsOnMobile: function() { - if (this.utils.isMobile() && this.opts.buttonsHideOnMobile.length !== 0) + if (this.detect.isMobile() && this.opts.buttonsHideOnMobile.length !== 0) { this.button.hideButtonsSlicer(this.opts.buttonsHideOnMobile); } @@ -1607,17 +1676,9 @@ $.each(this.opts.buttons, $.proxy(function(i, btnName) { - if (!this.toolbarsButtons[btnName]) - { - return; - } - - if (btnName === 'file' && (!this.opts.fileUpload || !this.opts.fileUpload && !this.opts.s3)) - { - return; - } - - if (btnName === 'image' && (!this.opts.imageUpload || !this.opts.imageUpload && !this.opts.s3)) + if (!this.toolbarsButtons[btnName] + || (btnName === 'file' && !this.file.is()) + || (btnName === 'image' && !this.image.is())) { return; } @@ -1628,6 +1689,11 @@ }, build: function(btnName, btnObject) { + if (this.opts.toolbar === false) + { + return; + } + var $button = $('').html(btnObject.title); $button.attr({ 'role': 'button', 'aria-label': btnObject.title, 'tabindex': '-1' }); @@ -1647,7 +1713,7 @@ { $button.addClass('redactor-toolbar-link-dropdown').attr('aria-haspopup', true); - var $dropdown = $('