Improved redactor integration
authorAlexander Ebert <ebert@woltlab.com>
Tue, 2 Feb 2016 12:43:09 +0000 (13:43 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Tue, 2 Feb 2016 12:43:09 +0000 (13:43 +0100)
com.woltlab.wcf/templates/wysiwyg.tpl
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabDropdown.js
wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabLink.js [new file with mode: 0644]
wcfsetup/install/files/js/WoltLab/WCF/Ui/Dialog.js
wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Link.js [new file with mode: 0644]
wcfsetup/install/files/style/ui/redactor.scss

index ab2aea0de06913d4824518bc04c3b788993a2b47..e12ed688ddc1483aeb53ead3ac41593d33d8b647 100644 (file)
@@ -27,7 +27,7 @@
                var config = {
                        buttons: buttons,
                        minHeight: 200,
-                       plugins: ['WoltLabButton', 'WoltLabDropdown', 'WoltLabEvent', 'WoltLabQuote'],
+                       plugins: ['WoltLabButton', 'WoltLabDropdown', 'WoltLabEvent', 'WoltLabLink', 'WoltLabQuote'],
                        woltlab: {
                                autosave: autosave
                        }
@@ -53,6 +53,7 @@
                '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabButton.js?v={@LAST_UPDATE_TIME}',
                '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabDropdown.js?v={@LAST_UPDATE_TIME}', 
                '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabEvent.js?v={@LAST_UPDATE_TIME}',
+               '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabLink.js?v={@LAST_UPDATE_TIME}',
                {if $__wcf->session->getPermission('admin.content.cms.canUseMedia')}'{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMedia.js?v={@LAST_UPDATE_TIME}',{/if}
                '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabMention.js?v={@LAST_UPDATE_TIME}',
                '{@$__wcf->getPath()}js/3rdParty/redactor2/plugins/WoltLabQuote.js?v={@LAST_UPDATE_TIME}'
index e313a9c5fcfa3ca65f653e50e776ca401315bf5d..44f7e9af616af31b7c32247164d2f4bbce49c66e 100644 (file)
@@ -17,8 +17,8 @@ $.Redactor.prototype.WoltLabDropdown = function() {
                
                _hideAll: function() {
                        var hideAll = this.dropdown.hideAll;
-                       this.dropdown.hideAll = (function() {
-                               hideAll.call(this);
+                       this.dropdown.hideAll = (function(e, key) {
+                               hideAll.call(this, e, key);
                                
                                $('.redactor-dropdown-' + this.uuid).stop(true, true).hide();
                        }).bind(this);
diff --git a/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabLink.js b/wcfsetup/install/files/js/3rdParty/redactor2/plugins/WoltLabLink.js
new file mode 100644 (file)
index 0000000..d2f6c61
--- /dev/null
@@ -0,0 +1,69 @@
+$.Redactor.prototype.WoltLabLink = function() {
+       "use strict";
+       
+       var _dialogApi = null;
+       
+       return {
+               init: function() {
+                       this.link.show = this.WoltLabLink.show.bind(this);
+                       
+                       require(['WoltLab/WCF/Ui/Redactor/Link'], function(UiRedactorLink) {
+                               _dialogApi = UiRedactorLink;
+                       });
+               },
+               
+               show: function(e) {
+                       // if call from clickable element
+                       if (typeof e !== 'undefined' && e.preventDefault)
+                       {
+                               e.preventDefault();
+                       }
+                       
+                       // close tooltip
+                       this.observe.closeAllTooltip();
+                       
+                       // is link
+                       var $el = this.link.is();
+                       
+                       // WoltLab START
+                       // this.link.buildModal($el);
+                       _dialogApi.showDialog({
+                               insert: ($el === false),
+                               submitCallback: (function() {
+                                       // build link
+                                       var link = this.link.buildLinkFromModal();
+                                       if (link === false) {
+                                               return false;
+                                       }
+                                       
+                                       this.selection.restore();
+                                       
+                                       // insert or update
+                                       this.link.insert(link, true);
+                                       
+                                       return true;
+                               }).bind(this)
+                       });
+                       // WoltLab END
+                       
+                       // build link
+                       var link = this.link.buildLinkFromElement($el);
+                       
+                       // if link cut & paste inside editor browser added self host to a link
+                       link.url = this.link.removeSelfHostFromUrl(link.url);
+                       
+                       // set modal values
+                       this.link.setModalValues(link);
+                       
+                       // WoltLab START
+                       // this.modal.show();
+                       // WoltLab END
+                       
+                       // focus
+                       if (this.detect.isDesktop())
+                       {
+                               $('#redactor-link-url').focus();
+                       }
+               }
+       };
+};
index 966e02b86c5a3fcb3b5db095aa2ea75eeaebc52f..10d4140fcfe9089f4347dff5125ee94255bd8b6c 100644 (file)
@@ -187,7 +187,6 @@ define(
                                        closeButtonLabel: Language.get('wcf.global.button.close'),
                                        closeConfirmMessage: '',
                                        disableContentPadding: false,
-                                       disposeOnClose: false,
                                        title: '',
                                        
                                        // callbacks
@@ -260,10 +259,6 @@ define(
                        elAttr(dialog, 'role', 'dialog');
                        elData(dialog, 'id', id);
                        
-                       if (options.disposeOnClose) {
-                               elData(dialog, 'dispose-on-close', true);
-                       }
-                       
                        var header = elCreate('header');
                        dialog.appendChild(header);
                        
@@ -500,17 +495,7 @@ define(
                                data.onClose(id);
                        }
                        
-                       if (elAttr(data.dialog, 'data-dispose-on-close')) {
-                               setTimeout(function() {
-                                       if (elAttr(data.dialog, 'aria-hidden') === 'true') {
-                                               _container.removeChild(data.dialog);
-                                               _dialogs['delete'](id);
-                                       }
-                               }, 5000);
-                       }
-                       else {
-                               elAttr(data.dialog, 'aria-hidden', 'true');
-                       }
+                       elAttr(data.dialog, 'aria-hidden', 'true');
                        
                        // get next active dialog
                        _activeDialog = null;
diff --git a/wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Link.js b/wcfsetup/install/files/js/WoltLab/WCF/Ui/Redactor/Link.js
new file mode 100644 (file)
index 0000000..b2d5f1e
--- /dev/null
@@ -0,0 +1,68 @@
+define(['Language', 'Ui/Dialog'], function(Language, UiDialog) {
+       "use strict";
+       
+       var _boundListener = false;
+       var _callback = null;
+       
+       return {
+               showDialog: function(options) {
+                       UiDialog.open(this);
+                       
+                       UiDialog.setTitle(this, Language.get('wcf.redactor.link.' + (options.insert ? 'add' : 'edit')));
+                       
+                       var submitButton = elById('redactor-modal-button-action');
+                       submitButton.textContent = Language.get('wcf.global.button.' + (options.insert ? 'insert' : 'save'));
+                       
+                       _callback = options.submitCallback;
+                       
+                       if (!_boundListener) {
+                               _boundListener = true;
+                               
+                               submitButton.addEventListener(WCF_CLICK_EVENT, this._submit.bind(this));
+                       }
+               },
+               
+               _submit: function() {
+                       if (_callback()) {
+                               UiDialog.close(this);
+                       }
+                       else {
+                               var url = elById('redactor-link-url');
+                               var small = (url.nextElementSibling && url.nextElementSibling.nodeName === 'SMALL') ? url.nextElementSibling : null;
+                               
+                               if (small === null) {
+                                       small = elCreate('small');
+                                       small.className = 'innerError';
+                                       small.textContent = Language.get('wcf.global.form.error.empty');
+                                       url.parentNode.appendChild(small);
+                               }
+                       }
+               },
+               
+               _dialogSetup: function() {
+                       return {
+                               id: 'redactorDialogLink',
+                               options: {
+                                       onClose: function() {
+                                               var url = elById('redactor-link-url');
+                                               var small = (url.nextElementSibling && url.nextElementSibling.nodeName === 'SMALL') ? url.nextElementSibling : null;
+                                               if (small !== null) {
+                                                       elRemove(small);
+                                               }
+                                       }
+                               },
+                               source: '<dl>'
+                                               + '<dt><label for="redactor-link-url">' + Language.get('wcf.redactor.link.url') + '</label></dt>'
+                                               + '<dd><input type="url" id="redactor-link-url" class="long"></dd>'
+                                       + '</dl>'
+                                       + '<dl>'
+                                               + '<dt><label for="redactor-link-url-text">' + Language.get('wcf.redactor.link.text') + '</label></dt>'
+                                               + '<dd><input type="text" id="redactor-link-url-text" class="long"></dd>'
+                                       + '</dl>'
+                                       + '<div class="formSubmit">'
+                                               + '<button id="redactor-modal-button-action" class="buttonPrimary"></button>'
+                                       + '</div>'
+                       };
+               }
+       };
+});
index 8909f161011d0167a56f32701b8e366c53ec5ec3..a8a4e5f5e0544ea2908fc2381815bf09431e19e0 100644 (file)
 .redactor-dropdown {
        > .dropdownMenu {
                display: block;
+               visibility: visible;
+               
+               /* we cannot influence the actual dropdown position as set by Redactor,
+                  forces a gap while keeping the inline top-attribute unaffected */
+               transform: translateY(3px);
                
                > li:hover {
                        background-color: transparent !important;