Added support for an i18n editor instance
authorAlexander Ebert <ebert@woltlab.com>
Fri, 10 Mar 2017 12:49:10 +0000 (13:49 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Fri, 10 Mar 2017 12:49:10 +0000 (13:49 +0100)
Related to #2188

com.woltlab.wcf/templates/multipleLanguageInputJavascript.tpl
wcfsetup/install/files/acp/templates/multipleLanguageInputJavascript.tpl
wcfsetup/install/files/js/WoltLabSuite/Core/Language/Input.js
wcfsetup/install/files/js/WoltLabSuite/Core/Language/Text.js [new file with mode: 0644]
wcfsetup/install/files/style/layout/form.scss

index 50830c088c57548a97fabf91aaac8383667f5ec0..2570fd2dd5943c18d3f9cbec2fd36b2cf717034d 100644 (file)
@@ -1,6 +1,6 @@
 {if $availableLanguages|count > 1}
        <script data-relocate="true">
-               require(['Language', 'WoltLabSuite/Core/Language/Input'], function(Language, LanguageInput) {
+               require(['Language', 'WoltLabSuite/Core/Language/Input', 'WoltLabSuite/Core/Language/Text'], function(Language, LanguageInput, LanguageText) {
                        Language.addObject({
                                'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}'
                        });
@@ -8,7 +8,13 @@
                        var availableLanguages = { {implode from=$availableLanguages key=languageID item=languageName}{@$languageID}: '{$languageName}'{/implode} };
                        var values = { {implode from=$i18nValues[$elementIdentifier] key=languageID item=value}'{@$languageID}': '{$value}'{/implode} };
                        
-                       LanguageInput.init('{@$elementIdentifier}', values, availableLanguages, {if $forceSelection}true{else}false{/if});
+                       var element = elById('{@$elementIdentifier}');
+                       var type = LanguageInput;
+                       if (element && element.nodeName === 'TEXTAREA' && element.classList.contains('wysiwygTextarea')) {
+                               type = LanguageText;
+                       }
+                       
+                       type['init']('{@$elementIdentifier}', values, availableLanguages, {if $forceSelection}true{else}false{/if});
                });
        </script>
 {/if}
index 50830c088c57548a97fabf91aaac8383667f5ec0..2570fd2dd5943c18d3f9cbec2fd36b2cf717034d 100644 (file)
@@ -1,6 +1,6 @@
 {if $availableLanguages|count > 1}
        <script data-relocate="true">
-               require(['Language', 'WoltLabSuite/Core/Language/Input'], function(Language, LanguageInput) {
+               require(['Language', 'WoltLabSuite/Core/Language/Input', 'WoltLabSuite/Core/Language/Text'], function(Language, LanguageInput, LanguageText) {
                        Language.addObject({
                                'wcf.global.button.disabledI18n': '{lang}wcf.global.button.disabledI18n{/lang}'
                        });
@@ -8,7 +8,13 @@
                        var availableLanguages = { {implode from=$availableLanguages key=languageID item=languageName}{@$languageID}: '{$languageName}'{/implode} };
                        var values = { {implode from=$i18nValues[$elementIdentifier] key=languageID item=value}'{@$languageID}': '{$value}'{/implode} };
                        
-                       LanguageInput.init('{@$elementIdentifier}', values, availableLanguages, {if $forceSelection}true{else}false{/if});
+                       var element = elById('{@$elementIdentifier}');
+                       var type = LanguageInput;
+                       if (element && element.nodeName === 'TEXTAREA' && element.classList.contains('wysiwygTextarea')) {
+                               type = LanguageText;
+                       }
+                       
+                       type['init']('{@$elementIdentifier}', values, availableLanguages, {if $forceSelection}true{else}false{/if});
                });
        </script>
 {/if}
index 7010fedf60cf237c0454a6904a181841deda6792..0e839e840cd03ccad5d3eb26b192655e79a1abe5 100644 (file)
@@ -54,6 +54,21 @@ define(['Core', 'Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traver
                        this._initElement(elementId, element, unescapedValues, availableLanguages, forceSelection);
                },
                
+               /**
+                * Registers a callback for an element.
+                * 
+                * @param       {string}        elementId
+                * @param       {string}        eventName
+                * @param       {function}      callback
+                */
+               registerCallback: function (elementId, eventName, callback) {
+                       if (!_values.has(elementId)) {
+                               throw new Error("Unknown element id '" + elementId + "'.");
+                       }
+                       
+                       _elements.get(elementId).callbacks.set(eventName, callback);
+               },
+               
                /**
                 * Caches common event listener callbacks.
                 */
@@ -157,6 +172,7 @@ define(['Core', 'Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traver
                        
                        _elements.set(elementId, {
                                buttonLabel: button.children[0],
+                               callbacks: new Dictionary(),
                                element: element,
                                languageId: 0,
                                isEnabled: true,
@@ -192,7 +208,7 @@ define(['Core', 'Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traver
                _select: function(elementId, languageId, isInit) {
                        var data = _elements.get(elementId);
                        
-                       var dropdownMenu = UiSimpleDropdown.getDropdownMenu(data.element.parentNode.id);
+                       var dropdownMenu = UiSimpleDropdown.getDropdownMenu(data.element.closest('.inputAddon').id);
                        var item, label = '';
                        for (var i = 0, length = dropdownMenu.childElementCount; i < length; i++) {
                                item = dropdownMenu.children[i];
@@ -229,6 +245,10 @@ define(['Core', 'Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traver
                                data.element.blur();
                                data.element.focus();
                        }
+                       
+                       if (data.callbacks.has('select')) {
+                               data.callbacks.get('select')(data.element);
+                       }
                },
                
                /**
@@ -283,6 +303,10 @@ define(['Core', 'Dictionary', 'Language', 'ObjectMap', 'StringUtil', 'Dom/Traver
                                if (data.isEnabled) {
                                        values = _values.get(elementId);
                                        
+                                       if (data.callbacks.has('submit')) {
+                                               data.callbacks.get('submit')(data.element);
+                                       }
+                                       
                                        // update with current value
                                        if (data.languageId) {
                                                values.set(data.languageId, data.element.value);
diff --git a/wcfsetup/install/files/js/WoltLabSuite/Core/Language/Text.js b/wcfsetup/install/files/js/WoltLabSuite/Core/Language/Text.js
new file mode 100644 (file)
index 0000000..05c260a
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * I18n interface for wysiwyg input fields.
+ * 
+ * @author      Alexander Ebert
+ * @copyright   2001-2017 WoltLab GmbH
+ * @license     GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module      WoltLabSuite/Core/Language/Text
+ */
+define(['Core', './Input'], function (Core, LanguageInput) {
+       "use strict";
+       
+       /**
+        * @exports     WoltLabSuite/Core/Language/Text
+        */
+       return {
+               /**
+                * Initializes an WYSIWYG input field.
+                * 
+                * @param       {string}        elementId               input element id
+                * @param       {Object}        values                  preset values per language id
+                * @param       {Object}        availableLanguages      language names per language id
+                * @param       {boolean}       forceSelection          require i18n input
+                */
+               init: function(elementId, values, availableLanguages, forceSelection) {
+                       var element = elById(elementId);
+                       if (!element || element.nodeName !== 'TEXTAREA' || !element.classList.contains('wysiwygTextarea')) {
+                               throw new Error("Expected <textarea class=\"wysiwygTextarea\" /> for id '" + elementId + "'.");
+                       }
+                       
+                       LanguageInput.init(elementId, values, availableLanguages, forceSelection);
+                       
+                       //noinspection JSUnresolvedFunction
+                       LanguageInput.registerCallback(elementId, 'select', this._callbackSelect.bind(this));
+                       //noinspection JSUnresolvedFunction
+                       LanguageInput.registerCallback(elementId, 'submit', this._callbackSubmit.bind(this));
+               },
+               
+               /**
+                * Refreshes the editor content on language switch.
+                * 
+                * @param       {Element}       element         input element
+                * @protected
+                */
+               _callbackSelect: function (element) {
+                       if (window.jQuery !== undefined) {
+                               window.jQuery(element).redactor('code.set', element.value);
+                       }
+               },
+               
+               /**
+                * Refreshes the input element value on submit.
+                * 
+                * @param       {Element}       element         input element
+                * @protected
+                */
+               _callbackSubmit: function (element) {
+                       if (window.jQuery !== undefined) {
+                               element.value = window.jQuery(element).redactor('code.get');
+                       }
+               }
+       }
+});
index af36ea9e9328dcb99535ee7a8089107e0de3f9d5..672e09362132bea6c7d533fe2c0a5610b3f4fe77 100644 (file)
@@ -196,6 +196,11 @@ select {
        > textarea {
                flex: 0 0 100%;
        }
+       
+       > .redactor-box {
+               flex: 0 0 100%;
+               margin-top: 0 !important;
+       }
 }
 
 .inputAddon input,