[TASK] RTE: Migrate toolbar ExtJS combos to plain JavaScript 30/36130/5
authorStanislas Rolland <typo3@sjbr.ca>
Tue, 20 Jan 2015 03:33:54 +0000 (22:33 -0500)
committerStanislas Rolland <typo3@sjbr.ca>
Tue, 20 Jan 2015 18:03:58 +0000 (19:03 +0100)
Releases: master
Resolves: #64368
Change-Id: I28bc9b10f28a46eed21a0d86248dedef50e01922
Reviewed-on: http://review.typo3.org/36130
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
19 files changed:
typo3/sysext/rtehtmlarea/Classes/RteHtmlAreaBase.php
typo3/sysext/rtehtmlarea/Classes/SelectImage.php
typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/htmlarea.css
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Ajax/Ajax.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Configuration/Config.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Editor.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Framework.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Toolbar.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/Combo.js [deleted file]
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Plugin/Plugin.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Toolbar/Select.js [new file with mode: 0644]
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Util/String.js [new file with mode: 0644]
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/BlockElements.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/BlockStyle.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/InlineElements.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/Language.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SelectFont.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TextStyle.js
typo3/sysext/t3skin/rtehtmlarea/htmlarea.css

index 3d38b41..9d16b94 100644 (file)
@@ -810,6 +810,7 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
                        'Util/Util',
                        'Util/Color',
                        'Util/Resizable',
+                       'Util/String',
                        'Util/Tips',
                        'Util/TYPO3',
                        'Ajax/Ajax',
@@ -824,7 +825,7 @@ class RteHtmlAreaBase extends \TYPO3\CMS\Backend\Rte\AbstractRte {
                        'Configuration/Config',
                        'Toolbar/Button',
                        'Toolbar/ToolbarText',
-                       'Extjs/ux/Combo',
+                       'Toolbar/Select',
                        'Extjs/ColorPalette',
                        'Extjs/ux/ColorMenu',
                        'Extjs/ux/ColorPaletteField',
index 300ccdc..5aae754 100644 (file)
@@ -348,9 +348,10 @@ class SelectImage extends \TYPO3\CMS\Recordlist\Browser\ElementBrowser {
                                var floatSelector=\'<select id="iFloat" name="iFloat"><option value="">' . $GLOBALS['LANG']->getLL('notSet') . '</option><option value="none">' . $GLOBALS['LANG']->getLL('nonFloating') . '</option><option value="left">' . $GLOBALS['LANG']->getLL('left') . '</option><option value="right">' . $GLOBALS['LANG']->getLL('right') . '</option></select>\';
                                if (plugin.getButton("Language")) {
                                        var languageSelector = \'<select id="iLang" name="iLang">\';
-                                       plugin.getButton("Language").getStore().each(function (record) {
-                                               languageSelector +=\'<option value="\' + record.get("value") + \'">\' + record.get("text") + \'</option>\';
-                                       });
+                                       var options = plugin.getButton("Language").getOptions();
+                                       for (var i = 0, n = options.length; i < n; i++) {
+                                               languageSelector +=\'<option value="\' + options[i].value + \'">\' + options[i].innerHTML + \'</option>\';
+                                       }
                                        languageSelector += \'</select>\';
                                }
                                var sz="";
index 3cd0650..6452fc0 100644 (file)
 .htmlarea .toolbar .select {
        height: 17px;
 }
+.htmlarea .toolbar select {
+       border: 1px solid #c7c7c7;
+       border-radius: 2px;
+       display: inline-block;
+       height: 22px !important;
+       margin: 0 0 4px 0;
+       padding: 2px 1px;
+}
+.htmlarea .toolbar select option {
+       padding: 2px;
+}
 .htmlarea .toolbar .x-form-field-wrap .x-form-trigger {
        right: 0;
 }
index b97edf4..d1a119b 100644 (file)
@@ -26,81 +26,88 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Ajax/Ajax',
                Util.apply(this, config);
        };
 
-       /**
-        * Load a Javascript file asynchronously
-        *
-        * @param       string          url: url of the file to load
-        * @param       function        callBack: the callBack function
-        * @param       object          scope: scope of the callbacks
-        *
-        * @return      boolean         true on success of the request submission
-        */
-       Ajax.prototype.getJavascriptFile = function (url, callback, scope) {
-               var success = false,
-                       self = this,
-                       options = {
-                               callback: callback,
+       Ajax.prototype = {
+
+               /**
+                * Load a Javascript file asynchronously
+                *
+                * @param string url: url of the file to load
+                * @param function callBack: the callBack function
+                * @param object scope: scope of the callbacks
+                * @param string dataType: expected data type
+                *
+                * @return boolean true on success of the request submission
+                */
+               getJavascriptFile: function (url, callback, scope, dataType) {
+                       if (typeof dataType === 'undefined') {
+                               var dataType = 'script';
+                       }
+                       var success = false,
+                               self = this,
+                               options = {
+                                       callback: callback,
+                                       complete: function (response, status) {
+                                               this.callback.call(scope, options, success, response);
+                                       },
+                                       dataType: dataType,
+                                       error: function (response, status, error) {
+                                               self.editor.inhibitKeyboardInput = false;
+                                               self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'getJavascriptFile', 'Unable to get ' + url + ' . Server reported ' + error, 'error');
+                                       },
+                                       success: function (data, status, response) {
+                                               success = true;
+                                       },
+                                       scope: scope,
+                                       type: 'GET',
+                                       url: url
+                               };
+                       $.ajax(options);
+                       return success;
+               },
+
+               /**
+                * Post data to the server
+                *
+                * @param       string          url: url to post data to
+                * @param       object          data: data to be posted
+                * @param       function        callback: function that will handle the response returned by the server
+                * @param       object          scope: scope of the callbacks
+                *
+                * @return      boolean         true on success
+                */
+               postData: function (url, data, callback, scope) {
+                       var success = false,
+                               self = this;
+                       data.charset = this.editor.config.typo3ContentCharset ? this.editor.config.typo3ContentCharset : 'utf-8';
+                       var params = '';
+                       for (var parameter in data) {
+                               params += (params.length ? '&' : '') + parameter + '=' + encodeURIComponent(data[parameter]);
+                       }
+                       params += this.editor.config.RTEtsConfigParams;
+                       var options = {
+                               callback: typeof callback === 'function' ? callback : function (options, success, response) {
+                                       if (!success) {
+                                               self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'postData', 'Post request to ' + url + ' failed. Server reported ' + response.status, 'error');
+                                       }
+                               },
                                complete: function (response, status) {
                                        this.callback.call(scope, options, success, response);
                                },
-                               dataType: 'script',
-                               error: function (response, status, error) {
-                                       self.editor.inhibitKeyboardInput = false;
-                                       self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'getJavascriptFile', 'Unable to get ' + url + ' . Server reported ' + error, 'error');
+                               contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
+                               data: params,
+                               error: function (response) {
+                                       self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'postData', 'Unable to post ' + url + ' . Server reported ' + response.status, 'error');
                                },
-                               success: function (data, status, response) {
+                               success: function (response) {
                                        success = true;
                                },
                                scope: scope,
-                               type: 'GET',
+                               type: 'POST',
                                url: url
                        };
-               $.ajax(options);
-               return success;
-       };
-
-       /**
-        * Post data to the server
-        *
-        * @param       string          url: url to post data to
-        * @param       object          data: data to be posted
-        * @param       function        callback: function that will handle the response returned by the server
-        * @param       object          scope: scope of the callbacks
-        *
-        * @return      boolean         true on success
-        */
-       Ajax.prototype.postData = function (url, data, callback, scope) {
-               var success = false,
-                       self = this;
-               data.charset = this.editor.config.typo3ContentCharset ? this.editor.config.typo3ContentCharset : 'utf-8';
-               var params = '';
-               for (var parameter in data) {
-                       params += (params.length ? '&' : '') + parameter + '=' + encodeURIComponent(data[parameter]);
+                       $.ajax(options);
+                       return success;
                }
-               params += this.editor.config.RTEtsConfigParams;
-               var options = {
-                       callback: typeof callback === 'function' ? callback : function (options, success, response) {
-                               if (!success) {
-                                       self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'postData', 'Post request to ' + url + ' failed. Server reported ' + response.status, 'error');
-                               }
-                       },
-                       complete: function (response, status) {
-                               this.callback.call(scope, options, success, response);
-                       },
-                       contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
-                       data: params,
-                       error: function (response) {
-                               self.editor.appendToLog('HTMLArea/Ajax/Ajax', 'postData', 'Unable to post ' + url + ' . Server reported ' + response.status, 'error');
-                       },
-                       success: function (response) {
-                               success = true;
-                       },
-                       scope: scope,
-                       type: 'POST',
-                       url: url
-               };
-               $.ajax(options);
-               return success;
        };
 
        return Ajax;
index 589e46c..5e28c07 100644 (file)
@@ -87,25 +87,10 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Configuration/Config',
                                // Erratic behaviour of click event in WebKit and IE browsers
                                clickEvent: (UserAgent.isWebKit || UserAgent.isIE) ? 'mousedown' : 'click'
                        },
-                       htmlareacombo: {
+                       htmlareaselect: {
                                cls: 'select',
-                               typeAhead: true,
-                               lastQuery: '',
-                               triggerAction: 'all',
-                               editable: !UserAgent.isIE,
-                               selectOnFocus: !UserAgent.isIE,
-                               validationEvent: false,
-                               validateOnBlur: false,
-                               submitValue: false,
-                               forceSelection: true,
-                               mode: 'local',
-                               storeRoot: 'options',
-                               storeFields: [ { name: 'text'}, { name: 'value'}],
-                               valueField: 'value',
-                               displayField: 'text',
                                labelSeparator: '',
-                               hideLabel: true,
-                               tpl: '<tpl for="."><div title="{value}" style="text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               hideLabel: true
                        }
                };
        };
@@ -137,24 +122,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Configuration/Config',
                Util.applyIf(config, this.configDefaults[config.xtype]);
                // Set some additional properties
                switch (config.xtype) {
-                       case 'htmlareacombo':
-                               if (config.options) {
-                                               // Create combo array store
-                                       config.store = new Ext.data.ArrayStore({
-                                               autoDestroy:  true,
-                                               fields: config.storeFields,
-                                               data: config.options
-                                       });
-                               } else if (config.storeUrl) {
-                                               // Create combo json store
-                                       config.store = new Ext.data.JsonStore({
-                                               autoDestroy:  true,
-                                               autoLoad: true,
-                                               root: config.storeRoot,
-                                               fields: config.storeFields,
-                                               url: config.storeUrl
-                                       });
-                               }
+                       case 'htmlareaselect':
                                config.hideLabel = typeof config.fieldLabel !== 'string' || !config.fieldLabel.length || UserAgent.isIE6;
                                config.helpTitle = config.tooltip;
                                break;
index 8074490..3cd37e9 100644 (file)
@@ -72,6 +72,12 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                                this.wizards.style.display = 'none';
                        }
                }
+
+               // Create Ajax object
+               this.ajax = new Ajax({
+                       editor: this
+               });
+
                // Plugins register
                this.plugins = {};
                // Register the plugins included in the configuration
@@ -80,10 +86,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                                this.registerPlugin(plugin);
                        }
                }
-               // Create Ajax object
-               this.ajax = new Ajax({
-                       editor: this
-               });
 
                // Initiate loading of the CSS classes configuration
                this.getClassesConfiguration();
index 2ff272a..fa02a73 100644 (file)
@@ -264,6 +264,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                onFrameworkResize: function () {
                        Dom.setSize(this.iframe.getEl(), { width: this.getInnerWidth(), height: this.getInnerHeight()});
                        Dom.setSize(this.textArea, { width: this.getInnerWidth(), height: this.getInnerHeight()});
+                       this.toolbar.update();
                },
 
                /**
index 1f154c2..c3ad98c 100644 (file)
@@ -18,10 +18,10 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
        ['TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/Util',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Toolbar/Button',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Toolbar/ToolbarText'],
-       function (Util, Dom, Event, Combo, Button, ToolbarText) {
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Toolbar/ToolbarText',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Toolbar/Select'],
+       function (Util, Dom, Event, Button, ToolbarText, Select) {
 
        /**
         * Editor toolbar constructor
@@ -115,8 +115,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                                                                        case 'htmlareabutton':
                                                                                this.add(new Button(itemConfig));
                                                                                break;
-                                                                       case 'htmlareacombo':
-                                                                               this.add(new Combo(itemConfig));
+                                                                       case 'htmlareaselect':
+                                                                               this.add(new Select(itemConfig));
                                                                                break;
                                                                        case 'htmlareatoolbartext':
                                                                                this.add(new ToolbarText(itemConfig));
@@ -144,31 +144,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                        if (item.itemId) {
                                this.items[item.itemId] = item;
                        }
-                       switch (item.xtype) {
-                               case 'htmlareacombo':
-                                       var wrapDiv = document.createElement('div');
-                                       Dom.addClass(wrapDiv, 'x-form-item');
-                                       wrapDiv = this.el.appendChild(wrapDiv);
-                                       item.render(wrapDiv);
-                                       if (item.helpTitle) {
-                                               item.getEl().dom.setAttribute('title', item.helpTitle);
-                                       }
-                                       wrapDiv.appendChild(item.getEl().dom);
-                                       if (item.fieldLabel) {
-                                               var textDiv = document.createElement('div');
-                                               Dom.addClass(textDiv, 'x-form-item');
-                                               Dom.addClass(textDiv, 'toolbar-text');
-                                               var text = document.createElement('label');
-                                               text.innerHTML = item.fieldLabel;
-                                               Dom.addClass(text, 'x-form-item-label');
-                                               text.setAttribute('for', item.getEl().dom.id);
-                                               textDiv.appendChild(text);
-                                               this.el.insertBefore(textDiv, wrapDiv);
-                                       }
-                                       break;
-                               default:
-                                       item.render(this.el);
-                       }
+                       item.render(this.el);
                },
 
                /**
diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/Combo.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/Combo.js
deleted file mode 100644 (file)
index c036541..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * Ext.ux.form.HTMLAreaCombo extends Ext.form.ComboBox
- */
-define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
-       ['TYPO3/CMS/Rtehtmlarea/HTMLArea/UserAgent/UserAgent',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event'],
-       function (UserAgent, Dom, Event) {
-
-       var Combo = Ext.extend(Ext.form.ComboBox, {
-
-               /**
-                * Constructor
-                */
-               initComponent: function () {
-                       this.superClass = Combo.superclass;
-                       this.superClass.initComponent.call(this);
-                       this.isFirstExpand = true;
-                       this.addListener({
-                               afterrender: {
-                                       fn: this.initEventListeners,
-                                       single: true
-                               }
-                       });
-               },
-
-               /**
-                * Initialize listeners
-                */
-               initEventListeners: function () {
-                       var self = this;
-                       Event.on(this, 'HTMLAreaEventHotkey', function (event, key, event) { return self.onHotKey(key); });
-                       this.addListener({
-                               select: {
-                                       fn: this.onComboSelect
-                               },
-                               specialkey: {
-                                       fn: this.onSpecialKey
-                               },
-                               beforedestroy: {
-                                       fn: this.onBeforeDestroy,
-                                       single: true
-                               }
-                       });
-                       // Monitor toolbar updates in order to refresh the state of the combo
-                       Event.on(this.getToolbar(), 'HTMLAreaEventToolbarUpdate', function (event, mode, selectionEmpty, ancestors, endPointsInSameBlock) { Event.stopEvent(event); self.onUpdateToolbar(mode, selectionEmpty, ancestors, endPointsInSameBlock); return false; });
-                       // Monitor framework becoming ready
-                       Event.one(this.getToolbar().framework, 'HTMLAreaEventFrameworkReady', function (event) { Event.stopEvent(event); self.onFrameworkReady(); return false; });
-               },
-
-               /**
-                * Get a reference to the editor
-                */
-               getEditor: function() {
-                       return RTEarea[this.toolbar.editorId].editor;
-               },
-
-               /**
-                * Get a reference to the toolbar
-                */
-               getToolbar: function() {
-                       return this.toolbar;
-               },
-
-               /**
-                * Handler invoked when an item is selected in the dropdown list
-                */
-               onComboSelect: function (combo, record, index) {
-                       if (!combo.disabled) {
-                               var editor = this.getEditor();
-                                       // In IE, reclaim lost focus on the editor iframe and restore the bookmarked selection
-                               if (UserAgent.isIE) {
-                                       if (typeof this.savedRange === 'object' && this.savedRange !== null) {
-                                               editor.getSelection().selectRange(this.savedRange);
-                                               this.savedRange = null;
-                                       }
-                               }
-                                       // Invoke the plugin onChange handler
-                               this.plugins[this.action](editor, combo, record, index);
-                                       // In IE, bookmark the updated selection as the editor will be loosing focus
-                               if (UserAgent.isIE) {
-                                       this.savedRange = editor.getSelection().createRange();
-                                       this.triggered = true;
-                               }
-                               if (UserAgent.isOpera) {
-                                       editor.focus();
-                               }
-                               this.getToolbar().update();
-                       }
-                       return false;
-               },
-
-               /**
-                * Handler invoked when the trigger element is clicked
-                * In IE, need to reclaim lost focus for the editor in order to restore the selection
-                */
-               onTriggerClick: function () {
-                       this.superClass.onTriggerClick.call(this);
-                       // If opening upward of the field, the list is not positioned correctly on first expand
-                       if (this.isFirstExpand) {
-                               this.collapse();
-                               this.expand();
-                               this.isFirstExpand = false;
-                       }
-                       // In IE, avoid focus being stolen and selection being lost
-                       if (UserAgent.isIE) {
-                               this.triggered = true;
-                               this.getEditor().focus();
-                       }
-               },
-
-               /**
-                * Handler invoked when the trigger element is enabled
-                */
-               onEnable: function(){
-                       this.superClass.onEnable.apply(this, arguments);
-                       this.getEl().dom.setAttribute('disabled', '');
-                       Dom.removeClass(this.getEl().dom, 'buttonDisabled');
-               },
-
-               /**
-                * Handler invoked when the trigger element is disabled
-                */
-               onDisable: function(){
-                       this.superClass.onDisable.apply(this, arguments);
-                       this.getEl().dom.setAttribute('disabled', 'true');
-                       Dom.addClass(this.getEl().dom, 'buttonDisabled');
-               },
-
-               /**
-                * Handler invoked when the list of options is clicked in
-                */
-               onViewClick: function (doFocus) {
-                       // Avoid stealing focus from the editor
-                       this.superClass.onViewClick.call(this, false);
-               },
-
-               /**
-                * Handler invoked in IE when the mouse moves out of the editor iframe
-                */
-               saveSelection: function (event) {
-                       var editor = this.getEditor();
-                       if (editor.document.hasFocus()) {
-                               this.savedRange = editor.getSelection().createRange();
-                       }
-               },
-
-               /**
-                * Handler invoked in IE when the editor gets the focus back
-                */
-               restoreSelection: function (event) {
-                       if (typeof this.savedRange === 'object' && this.savedRange !== null && this.triggered) {
-                               this.getEditor().getSelection().selectRange(this.savedRange);
-                               this.triggered = false;
-                       }
-               },
-
-               /**
-                * Handler invoked when the enter key is pressed while the combo has focus
-                */
-               onSpecialKey: function (combo, event) {
-                       if (event.getKey() == event.ENTER) {
-                               event.stopEvent();
-                       }
-                       return false;
-               },
-
-               /**
-                * Handler invoked when a hot key configured for this dropdown list is pressed
-                */
-               onHotKey: function (key) {
-                       if (!this.disabled) {
-                               this.plugins.onHotKey(this.getEditor(), key);
-                               if (UserAgent.isOpera) {
-                                       this.getEditor().focus();
-                               }
-                               this.getToolbar().update();
-                       }
-                       return false;
-               },
-
-               /**
-                * Handler invoked when the toolbar is updated
-                */
-               onUpdateToolbar: function (mode, selectionEmpty, ancestors, endPointsInSameBlock) {
-                       this.setDisabled(mode === 'textmode' && !this.textMode);
-                       if (!this.disabled) {
-                               this.plugins['onUpdateToolbar'](this, mode, selectionEmpty, ancestors, endPointsInSameBlock);
-                       }
-               },
-
-               /**
-                * The iframe must have been rendered
-                */
-               onFrameworkReady: function () {
-                       var iframe = this.getEditor().iframe;
-                       // Close the combo on a click in the iframe
-                       // Note: ExtJS is monitoring events only on the parent window
-                       var self = this;
-                       Event.on(iframe.document.documentElement, 'click', function (event) { self.collapse(); return true; });
-                       // Special handling for combo stealing focus in IE
-                       if (UserAgent.isIE) {
-                               // Take a bookmark in case the editor looses focus by activation of this combo
-                               Event.on(iframe.getEl(), 'mouseleave', function (event) { self.saveSelection(event); return true; });
-                               // Restore the selection if combo was triggered
-                               Event.on(iframe.getEl(), 'focus', function (event) { self.restoreSelection(event); return true; });
-                       }
-               },
-
-               /**
-                * Cleanup
-                */
-               onBeforeDestroy: function () {
-                       this.savedRange = null;
-                       this.getStore().removeAll();
-                       this.getStore().destroy();
-               }
-       });
-
-       return Combo;
-
-});
index bada3f7..bbb8b87 100644 (file)
@@ -227,8 +227,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Plugin/Plugin',
                                if (typeof dropDownConfiguration.action === 'string' && dropDownConfiguration.action.length > 0 && typeof this[dropDownConfiguration.action] === 'function') {
                                        dropDownConfiguration.plugins = this;
                                        dropDownConfiguration.hidden = dropDownConfiguration.hide;
-                                       dropDownConfiguration.xtype = 'htmlareacombo';
-                                       // Apply additional ExtJS config properties set in Page TSConfig
+                                       dropDownConfiguration.xtype = 'htmlareaselect';
+                                       // Apply additional config properties set in Page TSConfig
                                        // May not always work for values that must be integers
                                        Util.applyIf(dropDownConfiguration, this.editorConfiguration.buttons[this.editorConfiguration.convertButtonId[dropDownConfiguration.id]]);
                                        return this.editorConfiguration.registerButton(dropDownConfiguration);
diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Toolbar/Select.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Toolbar/Select.js
new file mode 100644 (file)
index 0000000..8e6a222
--- /dev/null
@@ -0,0 +1,374 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * A select field in the toolbar
+ */
+define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Toolbar/Select',
+       ['TYPO3/CMS/Rtehtmlarea/HTMLArea/UserAgent/UserAgent',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/Util',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event',
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/String'],
+       function (UserAgent, Dom, Util, Event, UtilString) {
+
+       /**
+        * Select constructor
+        */
+       var Select = function (config) {
+               Util.apply(this, config);
+       };
+
+       Select.prototype = {
+
+               render: function () {
+                       this.el = document.createElement('div');
+                       Dom.addClass(this.el, 'x-form-item');
+                       this.selectElement = document.createElement('select');
+                       if (this.id) {
+                               this.selectElement.setAttribute('id', this.id);
+                       }
+                       if (typeof this.cls === 'string') {
+                               Dom.addClass(this.selectElement, this.cls);
+                       }
+                       if (typeof this.tooltip === 'string') {
+                               this.selectElement.setAttribute('title', this.tooltip);
+                       }
+                       if (this.width) {
+                               Dom.setStyle(this.selectElement, { width: this.width + 'px' } );
+                       } else {
+                               Dom.setStyle(this.selectElement, { width: '200px' } );
+                       }
+                       if (this.maxHeight) {
+                               Dom.setStyle(this.selectElement, { maxHeight: this.maxHeight + 'px' } );
+                       }
+                       if (this.options) {
+                               for (var i = 0, n = this.options.length; i < n; i++) {
+                                       this.addOption(this.options[i][0], this.options[i][1], this.options[i][1], this.options[i][2]);
+                               }
+                       }
+                       this.selectElement = this.el.appendChild(this.selectElement);
+                       this.el = this.getToolbar().getEl().appendChild(this.el);
+                       if (this.fieldLabel) {
+                               var textDiv = document.createElement('div');
+                               Dom.addClass(textDiv, 'x-form-item');
+                               Dom.addClass(textDiv, 'toolbar-text');
+                               var text = document.createElement('label');
+                               text.innerHTML = this.fieldLabel;
+                               Dom.addClass(text, 'x-form-item-label');
+                               text.setAttribute('for', this.selectElement.id);
+                               textDiv.appendChild(text);
+                               this.el.insertBefore(textDiv, this.selectElement);
+                       }
+                       this.selectedElementWidth = Dom.getSize(this.selectElement).width;
+                       this.initEventListeners();
+               },
+
+               /**
+                * Get the element to which the item is rendered
+                */
+               getEl: function () {
+                       return this.el;
+               },
+
+               /**
+                * Initialize listeners
+                */
+               initEventListeners: function () {
+                       var self = this;
+                       Event.on(this, 'HTMLAreaEventHotkey', function (event, key, keyEvent) { return self.onHotKey(key, keyEvent); });
+                       Event.on(this.selectElement, 'change', function (event) { return self.onChange(self, event); });
+                       // Handlers to change the selected option when the select is collapsed/expanded
+                       if (!UserAgent.isIE) {
+                               Event.on(this.selectElement, 'click', function (event) { self.onTrigger(event); });
+                               Event.on(window, 'mouseup', function (event) { if (event.target !== self.selectElement && !self.collapsed) { self.onTrigger(event); event.stopPropagation();}});
+                               Event.on(this.selectElement, 'blur', function (event) { if (!self.collapsed) { self.onTrigger(event); event.stopPropagation();}});
+                               Event.on(this.selectElement, 'keyup', function (event) { self.onEscape(event); });
+                       }
+                       // Monitor toolbar updates in order to refresh the state of the select
+                       Event.on(this.getToolbar(), 'HTMLAreaEventToolbarUpdate', function (event, mode, selectionEmpty, ancestors, endPointsInSameBlock) { Event.stopEvent(event); self.onUpdateToolbar(mode, selectionEmpty, ancestors, endPointsInSameBlock); return false; });
+               },
+
+               /**
+                * Get a reference to the editor
+                */
+               getEditor: function() {
+                       return this.getToolbar().getEditor();
+               },
+
+               /**
+                * Get a reference to the toolbar
+                */
+               getToolbar: function() {
+                       return this.toolbar;
+               },
+
+               /**
+                * Handler invoked when an item is selected in the dropdown list
+                */
+               onChange: function (select, event) {
+                       if (!select.disabled) {
+                               var editor = this.getEditor();
+                               // Invoke the plugin onChange handler
+                               this.plugins[this.action](editor, select);
+                               if (UserAgent.isOpera) {
+                                       editor.focus();
+                               }
+                               this.getToolbar().update();
+                       }
+                       return false;
+               },
+
+               /**
+                * State of the select dropdwon list
+                */
+               collapsed: true,
+
+               /**
+                * Handler for a click on the select
+                */
+               onTrigger: function (event) {
+                       this.collapsed = !this.collapsed;
+                       this.setSelectedOptionText();
+               },
+
+               /**
+                * Handler for an escape while focused on the select
+                */
+               onEscape: function (event) {
+                       if (Event.getKey(event) === Event.ESC && !this.collapsed) {
+                               this.onTrigger();
+                       }
+               },
+
+               /**
+                * Get the current value
+                *
+                * @return string the value attribute of the currently selected option
+                */
+               getValue: function () {
+                       return this.selectElement.options[this.selectElement.selectedIndex].value;
+               },
+
+               /**
+                * Set the current value
+                *
+                * @param string value: the value to be selected
+                * @return void
+                */
+               setValue: function (value) {
+                       var options = this.selectElement.options;
+                       for (var i = 0, n = options.length; i < n; i++) {
+                               if (options[i].value == value) {
+                                       this.selectElement.selectedIndex = i;
+                                       this.collapsed = true;
+                                       this.setSelectedOptionText();
+                                       break;
+                               }
+                       }
+               },
+
+               /**
+                * Find the index of the value
+                *
+                * @param string value: the value to be looked up
+                * @return int the index or -1
+                */
+               findValue: function (value) {
+                       var index = -1;
+                       var options = this.selectElement.options;
+                       for (var i = 0, n = options.length; i < n; i++) {
+                               if (options[i].value == value) {
+                                       index = i;
+                                       break;
+                               }
+                       }
+                       return index;
+               },
+
+               /**
+                * Set the text of the selected option
+                *
+                * @return void
+                */
+               setSelectedOptionText: function () {
+                       var option = this.selectElement.options[this.selectElement.selectedIndex];
+                       if (this.collapsed && !UserAgent.isIE) {
+                               option.innerHTML = option.getAttribute('data-htmlarea-text').ellipsis(this.selectedElementWidth - 20);
+                       } else {
+                               option.innerHTML = option.getAttribute('data-htmlarea-text');
+                       }
+               },
+
+               /**
+                * Set the first option of the select
+                *
+                * @param string text: the text of the option
+                * @param string value: the value of the option
+                * @param string title: the title of the option, if different from the value
+                * @return object the option
+                */
+               setFirstOption: function (text, value, title) {
+                       var option = this.selectElement.firstChild;
+                       if (!option) {
+                               var option = this.addOption(text, value, title);
+                       } else {
+                               option.innerHTML = text;
+                               option.setAttribute('value', value);
+                               if (typeof title !== 'undefined') {
+                                       option.setAttribute('title', title);
+                               } else {
+                                       option.setAttribute('title', value);
+                               }
+                       }
+                       return option;
+               },
+
+               /**
+                * Add an option to the select
+                *
+                * @param string text: the text of the option
+                * @param string value: the value of the option
+                * @param string title: the title of the option
+                * @param string style: the style of the option
+                * @return object the option
+                */
+               addOption: function (text, value, title, style) {
+                       var option = document.createElement('option');
+                       option.innerHTML = text;
+                       option.setAttribute('data-htmlarea-text', text);
+                       option.setAttribute('value', value);
+                       if (typeof title !== 'undefined') {
+                               option.setAttribute('title', title);
+                       } else {
+                               option.setAttribute('title', value);
+                       }
+                       if (typeof style === 'string' && style.length > 0) {
+                               option.style.cssText = style;
+                       }
+                       if (this.listWidth) {
+                               Dom.setStyle(option, { width: this.listWidth + 'px' } );
+                       }
+                       this.selectElement.add(option);
+                       return option;
+               },
+
+               /**
+                * Get the current options of the select element
+                *
+                * @return array the options of the select element
+                */
+               getOptions: function () {
+                       return this.selectElement.options;
+               },
+
+               /**
+                * Get the current count of options
+                *
+                * @return int the count
+                */
+               getCount: function () {
+                       return this.getOptions().length;
+               },
+
+               /**
+                * Remove the option at the specified index
+                *
+                * @param int index: the index of the option to be removed
+                * @return void
+                */
+               removeAt: function (index) {
+                       this.selectElement.remove(index);
+               },
+
+               /**
+                * Delete all options of the select element
+                *
+                * @return void
+                */
+               removeAll: function () {
+                       var index, options = this.getOptions();
+                       while (index = options.length) {
+                               this.selectElement.remove(0);
+                       }
+               },
+
+               /**
+                * Css class applied when the select element is disabled
+                */
+               disabledClass: 'buttonDisabled',
+
+               /**
+                * Setting disabled/enabled by boolean.
+                *
+                * @param boolean disabled
+                * @return void
+                */
+               setDisabled: function(disabled){
+                       this.disabled = disabled;
+                       if (disabled) {
+                               this.selectElement.setAttribute('disabled', 'true');
+                               Dom.addClass(this.selectElement, 'buttonDisabled');
+                       } else {
+                               this.selectElement.removeAttribute('disabled');
+                               Dom.removeClass(this.selectElement, this.disabledClass);
+                       }
+               },
+
+               /**
+                * Handler invoked when a hot key configured for this dropdown list is pressed
+                */
+               onHotKey: function (key) {
+                       if (!this.disabled) {
+                               this.plugins.onHotKey(this.getEditor(), key);
+                               if (UserAgent.isOpera) {
+                                       this.getEditor().focus();
+                               }
+                               this.getToolbar().update();
+                       }
+                       return false;
+               },
+
+               /**
+                * Handler invoked when the toolbar is updated
+                */
+               onUpdateToolbar: function (mode, selectionEmpty, ancestors, endPointsInSameBlock) {
+                       this.setDisabled(mode === 'textmode' && !this.textMode);
+                       if (!this.disabled) {
+                               this.plugins['onUpdateToolbar'](this, mode, selectionEmpty, ancestors, endPointsInSameBlock);
+                       }
+               },
+
+               /**
+                * Cleanup (called by toolbar onBeforeDestroy)
+                */
+               onBeforeDestroy: function () {
+                       Event.off(this);
+                       Event.off(this.selectElement);
+                       if (this.selectElement) {
+                               this.removeAll();
+                               this.selectElement = null;
+                       }
+                       if (this.el) {
+                               var node;
+                               while (node = this.el.firstChild) {
+                                       this.el.removeChild(node);
+                               }
+                               this.el = null;
+                       }
+               }
+       };
+
+       return Select;
+
+});
diff --git a/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Util/String.js b/typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Util/String.js
new file mode 100644 (file)
index 0000000..2d42ae3
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+/***************************************************
+ *  Color utilities
+ ***************************************************/
+define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/String',
+       ['TYPO3/CMS/Rtehtmlarea/HTMLArea/UserAgent/UserAgent'],
+       function (UserAgent) {
+
+       // Create the ruler
+       if (!document.getElementById('htmlarea-ruler')) {
+               // Insert the css rule in the stylesheet
+               var styleSheet = document.styleSheets[0];
+               var selector = '#htmlarea-ruler';
+               var style = 'visibility: hidden; white-space: nowrap;';
+               var rule = selector + ' { ' + style + ' }';
+               if (!UserAgent.isIEBeforeIE9) {
+                       try {
+                               styleSheet.insertRule(rule, styleSheet.cssRules.length);
+                       } catch (e) {}
+               } else {
+                       styleSheet.addRule(selector, style);
+               }
+               //Insert the ruler on the document
+               var ruler = document.createElement('span');
+               ruler.setAttribute('id', 'htmlarea-ruler');
+               document.body.appendChild(ruler);
+       }
+
+       /**
+        * Get the visual length of a string
+        */
+       String.prototype.visualLength = function() {
+               var ruler = document.getElementById('htmlarea-ruler');
+               ruler.innerHTML = this;
+               return ruler.offsetWidth;
+       };
+
+       /**
+        * Set an ellipsis on a string
+        */
+       String.prototype.ellipsis = function(length) {
+               var temp = this;
+               var trimmed = this;
+               if (temp.visualLength() > length) {
+                       trimmed += "...";
+                       while (trimmed.visualLength() > length) {
+                               temp = temp.substring(0, temp.length-1);
+                                       trimmed = temp + "...";
+                       }
+               }
+               return trimmed;
+       };
+});
index b93959e..d39fa3a 100644 (file)
@@ -32,6 +32,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                 * This function gets called by the class constructor
                 */
                configurePlugin: function (editor) {
+
                        /**
                         * Setting up some properties from PageTSConfig
                         */
@@ -40,24 +41,20 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                this.tags = this.editorConfiguration.buttons.blockstyle.tags;
                        }
                        this.useClass = {
-                               Indent          : "indent",
-                               JustifyLeft     : "align-left",
-                               JustifyCenter   : "align-center",
-                               JustifyRight    : "align-right",
-                               JustifyFull     : "align-justify"
+                               Indent          : 'indent',
+                               JustifyLeft     : 'align-left',
+                               JustifyCenter   : 'align-center',
+                               JustifyRight    : 'align-right',
+                               JustifyFull     : 'align-justify'
                        };
                        this.useAlignAttribute = false;
                        for (var buttonId in this.useClass) {
-                               if (this.useClass.hasOwnProperty(buttonId)) {
-                                       if (this.editorConfiguration.buttons[this.buttonList[buttonId][2]]) {
-                                               this.useClass[buttonId] = this.editorConfiguration.buttons[this.buttonList[buttonId][2]].useClass ? this.editorConfiguration.buttons[this.buttonList[buttonId][2]].useClass : this.useClass[buttonId];
-                                               if (buttonId === "Indent") {
-                                                       this.useBlockquote = this.editorConfiguration.buttons.indent.useBlockquote ? this.editorConfiguration.buttons.indent.useBlockquote : false;
-                                               } else {
-                                                       if (this.editorConfiguration.buttons[this.buttonList[buttonId][2]].useAlignAttribute) {
-                                                               this.useAlignAttribute = true;
-                                                       }
-                                               }
+                               this.useClass[buttonId] = this.buttonsConfiguration[this.buttonList[buttonId][2]] && this.buttonsConfiguration[this.buttonList[buttonId][2]].useClass ? this.buttonsConfiguration[this.buttonList[buttonId][2]].useClass : this.useClass[buttonId];
+                               if (buttonId === 'Indent') {
+                                       this.useBlockquote = this.buttonsConfiguration.indent && this.buttonsConfiguration.indent.useBlockquote ? this.buttonsConfiguration.indent.useBlockquote : false;
+                               } else {
+                                       if (this.buttonsConfiguration[this.buttonList[buttonId][2]] && this.buttonsConfiguration[this.buttonList[buttonId][2]].useAlignAttribute) {
+                                               this.useAlignAttribute = true;
                                        }
                                }
                        }
@@ -78,7 +75,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                        }
                                // Build lists of mutually exclusive class names
                        for (var tagName in this.formatBlockItems) {
-                               if (this.formatBlockItems.hasOwnProperty(tagName) && this.formatBlockItems[tagName].tagName && this.formatBlockItems[tagName].addClass) {
+                               if (this.formatBlockItems[tagName].tagName && this.formatBlockItems[tagName].addClass) {
                                        if (!this.formatBlockItems[this.formatBlockItems[tagName].tagName]) {
                                                this.formatBlockItems[this.formatBlockItems[tagName].tagName] = {};
                                        }
@@ -89,11 +86,12 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                }
                        }
                        for (var tagName in this.formatBlockItems) {
-                               if (this.formatBlockItems.hasOwnProperty(tagName) && this.formatBlockItems[tagName].classList) {
-                                       this.formatBlockItems[tagName].classList = new RegExp( "^(" + this.formatBlockItems[tagName].classList.join("|") + ")$");
+                               if (this.formatBlockItems[tagName].classList) {
+                                       this.formatBlockItems[tagName].classList = new RegExp( '^(' + this.formatBlockItems[tagName].classList.join('|') + ')$');
                                }
                        }
-                       /*
+
+                       /**
                         * Registering plugin "About" information
                         */
                        var pluginInformation = {
@@ -106,19 +104,21 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                license         : 'GPL'
                        };
                        this.registerPluginInformation(pluginInformation);
-       
-                       /*
+
+                       /**
                         * Registering the dropdown list
                         */
-                       var buttonId = "FormatBlock";
+                       var buttonId = 'FormatBlock';
                        var dropDownConfiguration = {
                                id: buttonId,
-                               tooltip: this.localize(buttonId + "-Tooltip"),
+                               tooltip: this.localize(buttonId + '-Tooltip'),
                                options: this.buttonsConfiguration.formatblock ? this.buttonsConfiguration.formatblock.options : [],
-                               action: "onChange"
+                               action: 'onChange'
                        };
                        if (this.buttonsConfiguration.formatblock) {
-                               dropDownConfiguration.width = this.buttonsConfiguration.formatblock.width ? parseInt(this.buttonsConfiguration.formatblock.width, 10) : 200;
+                               if (this.buttonsConfiguration.formatblock.width) {
+                                       dropDownConfiguration.width = parseInt(this.buttonsConfiguration.formatblock.width, 10);
+                               }
                                if (this.buttonsConfiguration.formatblock.listWidth) {
                                        dropDownConfiguration.listWidth = parseInt(this.buttonsConfiguration.formatblock.listWidth, 10);
                                }
@@ -127,7 +127,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                }
                        }
                        this.registerDropDown(dropDownConfiguration);
-                       /*
+
+                       /**
                         * Establishing the list of allowed block elements
                         */
                        var blockElements = new Array(), option;
@@ -142,18 +143,19 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                        } else {
                                this.allowedBlockElements = this.standardBlockElements;
                        }
-                       /*
+
+                       /**
                         * Registering hot keys for the dropdown list items
                         */
                        var blockElement, configuredHotKey;
                        for (var i = 0, n = blockElements.length; i < n; i++) {
                                blockElement = blockElements[i];
                                configuredHotKey = this.defaultHotKeys[blockElement];
-                               if (this.editorConfiguration.buttons.formatblock
-                                               && this.editorConfiguration.buttons.formatblock.items
-                                               && this.editorConfiguration.buttons.formatblock.items[blockElement]
-                                               && this.editorConfiguration.buttons.formatblock.items[blockElement].hotKey) {
-                                       configuredHotKey = this.editorConfiguration.buttons.formatblock.items[blockElement].hotKey;
+                               if (this.buttonsConfiguration.formatblock
+                                               && this.buttonsConfiguration.formatblock.items
+                                               && this.buttonsConfiguration.formatblock.items[blockElement]
+                                               && this.buttonsConfiguration.formatblock.items[blockElement].hotKey) {
+                                       configuredHotKey = this.buttonsConfiguration.formatblock.items[blockElement].hotKey;
                                }
                                if (configuredHotKey) {
                                        var hotKeyConfiguration = {
@@ -164,7 +166,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                        this.registerHotKey(hotKeyConfiguration);
                                }
                        }
-                       /*
+
+                       /**
                         * Registering the buttons
                         */
                        for (var buttonId in this.buttonList) {
@@ -184,7 +187,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                        }
                        return true;
                },
-               /*
+
+               /**
                 * The list of buttons added by this plugin
                 */
                buttonList: {
@@ -219,22 +223,28 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                isAllowedBlockElement: function (blockName) {
                        return this.allowedBlockElements.test(blockName);
                },
-               /*
+
+               /**
                 * This function adds an attribute to the array of attributes allowed on block elements
                 *
-                * @param       string  attribute: the name of the attribute to be added to the array
-                *
-                * @return      void
+                * @param string attribute: the name of the attribute to be added to the array
+                * @return void
                 */
                addAllowedAttribute: function (attribute) {
                        this.allowedAttributes.push(attribute);
                },
-               /*
+
+               /**
                 * This function gets called when some block element was selected in the drop-down list
                 */
-               onChange: function (editor, combo, record, index) {
-                       this.applyBlockElement(combo.itemId, combo.getValue());
+               onChange: function (editor, select) {
+                       var blockElement = select.getValue();
+                       this.applyBlockElement(select.itemId, blockElement);
                },
+
+               /**
+                * This function applies to the selection the markup chosen in the drop-down list or corresponding to the button pressed
+                */
                applyBlockElement: function (buttonId, blockElement) {
                        var tagName = blockElement;
                        var className = null;
@@ -1027,7 +1037,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                }
                        }
                },
-               /*
+
+               /**
                 * This function gets called when the toolbar is updated
                 */
                onUpdateToolbar: function (button, mode, selectionEmpty, ancestors, endPointsInSameBlock) {
@@ -1162,42 +1173,43 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockElements',
                                }
                        }
                },
-               /*
+
+               /**
                 * This function updates the drop-down list of block elements
                 */
                updateDropDown: function(select, deepestBlockAncestor, startAncestor) {
-                       var store = select.getStore();
-                       store.removeAt(0);
                        var index = -1;
                        if (deepestBlockAncestor) {
                                var nodeName = deepestBlockAncestor.nodeName.toLowerCase();
-                                       // Could be a custom item ...
-                               index = store.findBy(function(record, id) {
-                                       var item = this.formatBlockItems[record.get('value')];
-                                       return item && item.tagName == nodeName && item.addClass && Dom.hasClass(deepestBlockAncestor, item.addClass);
-                               }, this);
-                               if (index == -1) {
-                                               // ... or a standard one
-                                       index = store.findExact('value', nodeName);
+                               // Could be a custom item ...
+                               var options = select.getOptions();
+                               for (var i = 0, n = options.length; i < n; i++) {
+                                       var item = this.formatBlockItems[options[i].value];
+                                       if (item && item.tagName === nodeName && item.addClass && Dom.hasClass(deepestBlockAncestor, item.addClass)) {
+                                               index = i;
+                                               break;
+                                       }
+                               }
+                               if (index === -1) {
+                                       // ... or a standard one
+                                       index = select.findValue(nodeName);
                                }
                        }
-                       if (index == -1) {
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('No block'),
-                                       value: 'none'
-                               }));
+                       if (index === -1) {
+                               var text = this.localize('No block');
+                               select.setFirstOption(text, 'none', text);
                                select.setValue('none');
                        } else {
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('Remove block'),
-                                       value: 'none'
-                               }));
-                               select.setValue(store.getAt(index+1).get('value'));
+                               var text = this.localize('Remove block');
+                               select.setFirstOption(text, 'none', text);
+                               var options = select.getOptions();
+                               select.setValue(options[index].value);
                        }
                },
-               /*
-               * This function handles the hotkey events registered on elements of the dropdown list
-               */
+
+               /**
+                * This function handles the hotkey events registered on elements of the dropdown list
+                */
                onHotKey: function(editor, key) {
                        var blockElement;
                        var hotKeyConfiguration = this.getHotKeyConfiguration(key);
index 42eff16..41a6940 100644 (file)
@@ -38,16 +38,12 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                        this.tags = (this.pageTSconfiguration && this.pageTSconfiguration.tags) ? this.pageTSconfiguration.tags : {};
                        var allowedClasses;
                        for (var tagName in this.tags) {
-                               if (this.tags.hasOwnProperty(tagName)) {
-                                       if (this.tags[tagName].allowedClasses) {
-                                               allowedClasses = this.tags[tagName].allowedClasses.trim().split(",");
-                                               for (var cssClass in allowedClasses) {
-                                                       if (allowedClasses.hasOwnProperty(cssClass)) {
-                                                               allowedClasses[cssClass] = allowedClasses[cssClass].trim().replace(/\*/g, ".*");
-                                                       }
-                                               }
-                                               this.tags[tagName].allowedClasses = new RegExp( "^(" + allowedClasses.join("|") + ")$", "i");
+                               if (this.tags[tagName].allowedClasses) {
+                                       allowedClasses = this.tags[tagName].allowedClasses.trim().split(",");
+                                       for (var i = allowedClasses.length; --i >= 0;) {
+                                               allowedClasses[i] = allowedClasses[i].trim().replace(/\*/g, ".*");
                                        }
+                                       this.tags[tagName].allowedClasses = new RegExp( "^(" + allowedClasses.join("|") + ")$", "i");
                                }
                        }
                        this.showTagFreeClasses = this.pageTSconfiguration ? this.pageTSconfiguration.showTagFreeClasses : false;
@@ -66,6 +62,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                                license         : 'GPL'
                        };
                        this.registerPluginInformation(pluginInformation);
+
                        /**
                         * Registering the drop-down list
                         */
@@ -79,9 +76,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                                tooltip: this.localize(dropDownId + '-Tooltip'),
                                fieldLabel: fieldLabel,
                                options: [[this.localize('No style'), 'none']],
-                               action: 'onChange',
-                               storeFields: [ { name: 'text'}, { name: 'value'}, { name: 'style'} ],
-                               tpl: '<tpl for="."><div title="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               action: 'onChange'
                        };
                        if (this.pageTSconfiguration) {
                                if (this.pageTSconfiguration.width) {
@@ -101,8 +96,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                /**
                 * This handler gets called when some block style was selected in the drop-down list
                 */
-               onChange: function (editor, combo, record, index) {
-                       var className = combo.getValue();
+               onChange: function (editor, select) {
+                       var className = select.getValue();
                        this.editor.focus();
                        var blocks = this.editor.getSelection().getElements();
                        for (var k = 0; k < blocks.length; ++k) {
@@ -240,45 +235,82 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                 * This function reinitializes the options of the dropdown
                 */
                initializeDropDown: function (dropDown) {
-                       var store = dropDown.getStore();
-                       store.removeAll(false);
-                       store.insert(0, new store.recordType({
-                               text: this.localize('No style'),
-                               value: 'none'
-                       }));
-                       dropDown.setValue('none');
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       dropDown.removeAll();
+                                       dropDown.setFirstOption(this.localize('No style'), 'none', this.localize('No style'));
+                                       dropDown.setValue('none');
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       store.removeAll(false);
+                                       store.insert(0, new store.recordType({
+                                               text: this.localize('No style'),
+                                               value: 'none'
+                                       }));
+                                       dropDown.setValue('none');
+                                       break;
+                       }
                },
 
                /**
                 * This function builds the options to be displayed in the dropDown box
                 */
                buildDropDownOptions: function (dropDown, nodeName) {
-                       var store = dropDown.getStore();
                        this.initializeDropDown(dropDown);
-                       if (this.blockStyles.isReady()) {
-                               var allowedClasses = {};
-                               if (typeof this.cssArray[nodeName] !== 'undefined') {
-                                       allowedClasses = this.cssArray[nodeName];
-                               } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
-                                       allowedClasses = this.cssArray['all'];
-                               }
-                               for (var cssClass in allowedClasses) {
-                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
-                                               var style = null;
-                                               if (!this.pageTSconfiguration || !this.pageTSconfiguration.disableStyleOnOptionLabel) {
-                                                       if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
-                                                               style = HTMLArea.classesValues[cssClass];
-                                                       } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-'])  {
-                                                               style = HTMLArea.classesValues[RegExp.leftContext + '-'];
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       if (this.blockStyles.isReady()) {
+                                               var allowedClasses = {};
+                                               if (typeof this.cssArray[nodeName] !== 'undefined') {
+                                                       allowedClasses = this.cssArray[nodeName];
+                                               } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
+                                                       allowedClasses = this.cssArray['all'];
+                                               }
+                                               for (var cssClass in allowedClasses) {
+                                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                                               var style = null;
+                                                               if (!this.pageTSconfiguration || !this.pageTSconfiguration.disableStyleOnOptionLabel) {
+                                                                       if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
+                                                                               style = HTMLArea.classesValues[cssClass];
+                                                                       } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-'])  {
+                                                                               style = HTMLArea.classesValues[RegExp.leftContext + '-'];
+                                                                       }
+                                                               }
+                                                               dropDown.addOption(allowedClasses[cssClass], cssClass, cssClass, style);
                                                        }
                                                }
-                                               store.add(new store.recordType({
-                                                       text: allowedClasses[cssClass],
-                                                       value: cssClass,
-                                                       style: style
-                                               }));
                                        }
-                               }
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       this.initializeDropDown(dropDown);
+                                       if (this.blockStyles.isReady()) {
+                                               var allowedClasses = {};
+                                               if (typeof this.cssArray[nodeName] !== 'undefined') {
+                                                       allowedClasses = this.cssArray[nodeName];
+                                               } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
+                                                       allowedClasses = this.cssArray['all'];
+                                               }
+                                               for (var cssClass in allowedClasses) {
+                                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                                               var style = null;
+                                                               if (!this.pageTSconfiguration || !this.pageTSconfiguration.disableStyleOnOptionLabel) {
+                                                                       if (HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) {
+                                                                               style = HTMLArea.classesValues[cssClass];
+                                                                       } else if (/-[0-9]+$/.test(cssClass) && HTMLArea.classesValues[RegExp.leftContext + '-'])  {
+                                                                               style = HTMLArea.classesValues[RegExp.leftContext + '-'];
+                                                                       }
+                                                               }
+                                                               store.add(new store.recordType({
+                                                                       text: allowedClasses[cssClass],
+                                                                       value: cssClass,
+                                                                       style: style
+                                                               }));
+                                                       }
+                                               }
+                                       }
+                                       break;
                        }
                },
 
@@ -286,44 +318,88 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                 * This function sets the selected option of the dropDown box
                 */
                setSelectedOption: function (dropDown, classNames, noUnknown, defaultClass) {
-                       var store = dropDown.getStore();
-                       dropDown.setValue('none');
-                       if (classNames.length) {
-                               var index = store.findExact('value', classNames[classNames.length-1]);
-                               if (index !== -1) {
-                                       dropDown.setValue(classNames[classNames.length-1]);
-                                       if (!defaultClass) {
-                                               store.getAt(0).set('text', this.localize('Remove style'));
-                                       }
-                               }
-                               if (index === -1 && !noUnknown) {
-                                       var text = this.localize('Unknown style');
-                                       var value = classNames[classNames.length-1];
-                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
-                                               text = HTMLArea.classesLabels[value];
-                                       }
-                                       store.add(new store.recordType({
-                                               text: text,
-                                               value: value,
-                                               style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
-                                       }));
-                                       dropDown.setValue(value);
-                                       if (!defaultClass) {
-                                               store.getAt(0).set('text', this.localize('Remove style'));
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       dropDown.setValue('none');
+                                       if (classNames.length) {
+                                               var index = dropDown.findValue(classNames[classNames.length-1]);
+                                               if (index !== -1) {
+                                                       dropDown.setValue(classNames[classNames.length-1]);
+                                                       if (!defaultClass) {
+                                                               var text = this.localize('Remove style');
+                                                               dropDown.setFirstOption(text, 'none', text);
+                                                       }
+                                               }
+                                               if (index === -1 && !noUnknown) {
+                                                       var text = this.localize('Unknown style');
+                                                       var value = classNames[classNames.length-1];
+                                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                                               text = HTMLArea.classesLabels[value];
+                                                       }
+                                                       var style = (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null;
+                                                       dropDown.addOption(text, value, value, style);
+                                                       dropDown.setValue(value);
+                                                       if (!defaultClass) {
+                                                               text = this.localize('Remove style');
+                                                               dropDown.setFirstOption(text, 'none', text);
+                                                       }
+                                               }
+                                               // Remove already assigned classes from the dropDown box
+                                               var selectedValue = dropDown.getValue();
+                                               var options;
+                                               for (var i = 0, n = classNames.length; i < n; i++) {
+                                                       index = dropDown.findValue(classNames[i]);
+                                                       if (index !== -1) {
+                                                               options = dropDown.getOptions();
+                                                               if (options[index].value !== selectedValue) {
+                                                                       dropDown.removeAt(index);
+                                                               }
+                                                       }
+                                               }
                                        }
-                               }
-                               // Remove already assigned classes from the dropDown box
-                               var classNamesString = ',' + classNames.join(',') + ',';
-                               var selectedValue = dropDown.getValue(), optionValue;
-                               store.each(function (option) {
-                                       optionValue = option.get('value');
-                                       if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
-                                               store.removeAt(store.indexOf(option));
+                                       dropDown.setDisabled(!dropDown.getCount() || (dropDown.getCount() === 1 && dropDown.getValue() === 'none'));
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       dropDown.setValue('none');
+                                       if (classNames.length) {
+                                               var index = store.findExact('value', classNames[classNames.length-1]);
+                                               if (index !== -1) {
+                                                       dropDown.setValue(classNames[classNames.length-1]);
+                                                       if (!defaultClass) {
+                                                               store.getAt(0).set('text', this.localize('Remove style'));
+                                                       }
+                                               }
+                                               if (index === -1 && !noUnknown) {
+                                                       var text = this.localize('Unknown style');
+                                                       var value = classNames[classNames.length-1];
+                                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                                               text = HTMLArea.classesLabels[value];
+                                                       }
+                                                       store.add(new store.recordType({
+                                                               text: text,
+                                                               value: value,
+                                                               style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
+                                                       }));
+                                                       dropDown.setValue(value);
+                                                       if (!defaultClass) {
+                                                               store.getAt(0).set('text', this.localize('Remove style'));
+                                                       }
+                                               }
+                                               // Remove already assigned classes from the dropDown box
+                                               var classNamesString = ',' + classNames.join(',') + ',';
+                                               var selectedValue = dropDown.getValue(), optionValue;
+                                               store.each(function (option) {
+                                                       optionValue = option.get('value');
+                                                       if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
+                                                               store.removeAt(store.indexOf(option));
+                                                       }
+                                                       return true;
+                                               });
                                        }
-                                       return true;
-                               });
+                                       dropDown.setDisabled(!store.getCount() || (store.getCount() == 1 && dropDown.getValue() == 'none'));
+                                       break;
                        }
-                       dropDown.setDisabled(!store.getCount() || (store.getCount() == 1 && dropDown.getValue() == 'none'));
                }
        });
 
index 104984d..0b2c8ba 100644 (file)
@@ -31,6 +31,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                 * This function gets called by the base constructor
                 */
                configurePlugin: function (editor) {
+                       this.buttonsConfiguration = this.editorConfiguration.buttons;
                        // Setting the array of allowed attributes on inline elements
                        if (this.getPluginInstance('TextStyle')) {
                                this.allowedAttributes = this.getPluginInstance('TextStyle').allowedAttributes;
@@ -41,8 +42,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                                }
                        }
                        // Getting tags configuration for inline elements
-                       if (this.editorConfiguration.buttons.textstyle) {
-                               this.tags = this.editorConfiguration.buttons.textstyle.tags;
+                       if (this.buttonsConfiguration.textstyle) {
+                               this.tags = this.buttonsConfiguration.textstyle.tags;
                        }
 
                        /**
@@ -62,22 +63,27 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                        /**
                         * Registering the dropdown list
                         */
-                       var buttonId = "FormatText";
+                       var buttonId = 'FormatText';
+                       // Wrap the options text in the corresponding inline element
+                       var options = this.buttonsConfiguration[buttonId.toLowerCase()] ? this.buttonsConfiguration[buttonId.toLowerCase()].options : [];
+                       for (var i = 0, n = options.length; i < n; i++) {
+                               options[i][0] = '<' + options[i][1] + '>' + options[i][0] + '</' + options[i][1] + '>';
+                       }
                        var dropDownConfiguration = {
                                id              : buttonId,
-                               tooltip         : this.localize(buttonId + "-Tooltip"),
-                               options         : (this.editorConfiguration.buttons[buttonId.toLowerCase()] ? this.editorConfiguration.buttons[buttonId.toLowerCase()].options : []),
-                               action          : "onChange"
+                               tooltip         : this.localize(buttonId + '-Tooltip'),
+                               options         : options,
+                               action          : 'onChange'
                        };
-                       if (this.editorConfiguration.buttons.formattext) {
-                               if (this.editorConfiguration.buttons.formattext.width) {
-                                       dropDownConfiguration.listWidth = parseInt(this.editorConfiguration.buttons.formattext.width, 10);
+                       if (this.buttonsConfiguration.formattext) {
+                               if (this.buttonsConfiguration.formattext.width) {
+                                       dropDownConfiguration.width = parseInt(this.buttonsConfiguration.formattext.width, 10);
                                }
-                               if (this.editorConfiguration.buttons.formattext.listWidth) {
-                                       dropDownConfiguration.listWidth = parseInt(this.editorConfiguration.buttons.formattext.listWidth, 10);
+                               if (this.buttonsConfiguration.formattext.listWidth) {
+                                       dropDownConfiguration.listWidth = parseInt(this.buttonsConfiguration.formattext.listWidth, 10);
                                }
-                               if (this.editorConfiguration.buttons.formattext.maxHeight) {
-                                       dropDownConfiguration.maxHeight = parseInt(this.editorConfiguration.buttons.formattext.maxHeight, 10);
+                               if (this.buttonsConfiguration.formattext.maxHeight) {
+                                       dropDownConfiguration.maxHeight = parseInt(this.buttonsConfiguration.formattext.maxHeight, 10);
                                }
                        }
                        this.registerDropDown(dropDownConfiguration);
@@ -91,10 +97,10 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                                buttonId = button[0];
                                var buttonConfiguration = {
                                        id              : buttonId,
-                                       tooltip         : this.localize(buttonId + "-Tooltip"),
+                                       tooltip         : this.localize(buttonId + '-Tooltip'),
                                        contextMenuTitle: this.localize(buttonId + '-contextMenuTitle'),
                                        helpText        : this.localize(buttonId + '-helpText'),
-                                       action          : "onButtonPress",
+                                       action          : 'onButtonPress',
                                        context         : button[1],
                                        hide            : false,
                                        selection       : false,
@@ -180,7 +186,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                addAllowedAttribute: function (attribute) {
                        this.allowedAttributes.push(attribute);
                },
-               /*
+
+               /**
                 * This function gets called when some inline element button was pressed.
                 */
                onButtonPress: function (editor, id) {
@@ -195,14 +202,16 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                                this.appendToLog('onButtonPress', 'No element corresponding to button: ' + buttonId, 'warn');
                        }
                },
-               /*
+
+               /**
                 * This function gets called when some inline element was selected in the drop-down list
                 */
-               onChange: function (editor, combo, record, index) {
-                       var element = combo.getValue();
+               onChange: function (editor, select) {
+                       var element = select.getValue();
                        this.applyInlineElement(editor, element, false);
                },
-               /*
+
+               /**
                 * This function applies to the selection the markup chosen in the drop-down list or corresponding to the button pressed
                 */
                applyInlineElement: function (editor, element) {
@@ -299,7 +308,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                                }
                        }
                },
-               /*
+
+               /**
                 * This function remaps the given element to the specified tagname
                 */
                remapMarkup: function (element, tagName) {
@@ -344,9 +354,10 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                        }
                        return newElement;
                },
-               /*
-               * This function gets called when the toolbar is updated
-               */
+
+               /**
+                * This function gets called when the toolbar is updated
+                */
                onUpdateToolbar: function (button, mode, selectionEmpty, ancestors, endPointsInSameBlock) {
                        var editor = this.editor;
                        if (mode === 'wysiwyg' && editor.isEditable()) {
@@ -390,22 +401,16 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/InlineElements',
                 * This function updates the drop-down list of inline elemenents
                 */
                updateValue: function (editor, select, tagName, selectionEmpty, fullNodeSelected, disabled) {
-                       var store = select.getStore();
-                       store.removeAt(0);
-                       if ((store.findExact('value', tagName) != -1) && (selectionEmpty || fullNodeSelected)) {
+                       if ((select.findValue(tagName) !== -1) && (selectionEmpty || fullNodeSelected)) {
+                               var text = this.localize('Remove markup');
+                               select.setFirstOption(text, 'none', text);
                                select.setValue(tagName);
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('Remove markup'),
-                                       value: 'none'
-                               }));
                        } else {
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('No markup'),
-                                       value: 'none'
-                               }));
+                               var text = this.localize('No markup');
+                               select.setFirstOption(text, 'none', text);
                                select.setValue('none');
                        }
-                       select.setDisabled(!(store.getCount()>1) || disabled);
+                       select.setDisabled(!(select.getCount() > 1) || disabled);
                }
        });
 
index a844d66..08d0c2f 100644 (file)
@@ -59,7 +59,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                                        this.allowedAttributes.push('className');
                                }
                        }
-                       /*
+
+                       /**
                         * Registering plugin "About" information
                         */
                        var pluginInformation = {
@@ -72,7 +73,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                                license         : 'GPL'
                        };
                        this.registerPluginInformation(pluginInformation);
-                       /*
+
+                       /**
                         * Registering the buttons
                         */
                        var buttonList = this.buttonList, buttonId;
@@ -88,7 +90,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                                };
                                this.registerButton(buttonConfiguration);
                        }
-                       /*
+
+                       /**
                         * Registering the dropdown list
                         */
                        var buttonId = 'Language';
@@ -96,11 +99,12 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                                var dropDownConfiguration = {
                                        id              : buttonId,
                                        tooltip         : this.localize(buttonId + '-Tooltip'),
-                                       storeUrl        : this.buttonsConfiguration[buttonId.toLowerCase()].dataUrl,
                                        action          : 'onChange'
                                };
                                if (this.buttonsConfiguration.language) {
-                                       dropDownConfiguration.width = this.buttonsConfiguration.language.width ? parseInt(this.buttonsConfiguration.language.width, 10) : 200;
+                                       if (this.buttonsConfiguration.language.width) {
+                                               dropDownConfiguration.width = parseInt(this.buttonsConfiguration.language.width, 10);
+                                       }
                                        if (this.buttonsConfiguration.language.listWidth) {
                                                dropDownConfiguration.listWidth = parseInt(this.buttonsConfiguration.language.listWidth, 10);
                                        }
@@ -112,7 +116,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                        }
                        return true;
                },
-               /*
+
+               /**
                 * The list of buttons added by this plugin
                 */
                buttonList: [
@@ -120,28 +125,38 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                        ['RightToLeft', null, 'text-direction-right-to-left'],
                        ['ShowLanguageMarks', null, 'language-marks-show']
                ],
-               /*
+
+               /**
                 * This function gets called when the editor is generated
                 */
                onGenerate: function () {
                        var select = this.getButton('Language');
                        if (select) {
-                               if (select.getStore().getCount() > 1) {
+                               if (select.getCount() > 1) {
                                        this.addLanguageMarkingRules();
                                } else {
-                                               // Monitor the language combo's store being loaded
-                                       select.mon(select.getStore(), 'load', function () {
-                                               this.addLanguageMarkingRules();
-                                               var selection = this.editor.getSelection(),
-                                                       selectionEmpty = selection.isEmpty(),
-                                                       ancestors = selection.getAllAncestors(),
-                                                       endPointsInSameBlock = selection.endPointsInSameBlock();
-                                               this.onUpdateToolbar(select, this.getEditorMode(), selectionEmpty, ancestors, endPointsInSameBlock);
-                                       }, this);
+                                       // Monitor the language select options being loaded
+                                       this.editor.ajax.getJavascriptFile(this.buttonsConfiguration['language'].dataUrl, function (options, success, response) {
+                                               if (success && response['responseJSON']) {
+                                                       var options = response['responseJSON']['options'];
+                                                       if (options) {
+                                                               for (var i = 1, n = options.length; i < n; i++) {
+                                                                       select.addOption(options[i]['text'], options[i]['value'], options[i]['value']);
+                                                               }
+                                                               this.addLanguageMarkingRules();
+                                                               var selection = this.editor.getSelection(),
+                                                                       selectionEmpty = selection.isEmpty(),
+                                                                       ancestors = selection.getAllAncestors(),
+                                                                       endPointsInSameBlock = selection.endPointsInSameBlock();
+                                                               this.onUpdateToolbar(select, this.getEditorMode(), selectionEmpty, ancestors, endPointsInSameBlock);
+                                                       }
+                                               }
+                                       }, this, 'json');
                                }
                        }
                },
-               /*
+
+               /**
                 * This function adds rules to the stylesheet for language mark highlighting
                 * Model: body.htmlarea-show-language-marks *[lang=en]:before { content: "en: "; }
                 * Works in IE8, but not in earlier versions of IE
@@ -150,10 +165,13 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                        var select = this.getButton('Language');
                        if (select) {
                                var styleSheet = this.editor.document.styleSheets[0];
-                               select.getStore().each(function (option) {
-                                       var selector = 'body.htmlarea-show-language-marks *[' + 'lang="' + option.get('value') + '"]:before';
-                                       var style = 'content: "' + option.get('value') + ': ";';
-                                       var rule = selector + ' { ' + style + ' }';
+                               var options = select.getOptions();
+                               var selector, style, rule;
+                               for (var i = 0, n = options.length; i < n; i++) {
+                                       var option = options[i];
+                                       selector = 'body.htmlarea-show-language-marks *[' + 'lang="' + option.value + '"]:before';
+                                       style = 'content: "' + option.value + ': ";';
+                                       rule = selector + ' { ' + style + ' }';
                                        if (!UserAgent.isIEBeforeIE9) {
                                                try {
                                                        styleSheet.insertRule(rule, styleSheet.cssRules.length);
@@ -163,8 +181,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                                        } else {
                                                styleSheet.addRule(selector, style);
                                        }
-                                       return true;
-                               }, this);
+                               }
                        }
                },
 
@@ -231,8 +248,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                /*
                 * This function gets called when some language was selected in the drop-down list
                 */
-               onChange: function (editor, combo, record, index) {
-                       this.applyLanguageMark(combo.getValue());
+               onChange: function (editor, select) {
+                       this.applyLanguageMark(select.getValue());
                },
                /*
                 * This function applies the langauge mark to the selection
@@ -445,22 +462,16 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Language',
                 * This function updates the language drop-down list
                 */
                updateValue: function (select, language, selectionEmpty, fullNodeSelected, endPointsInSameBlock) {
-                       var store = select.getStore();
-                       store.removeAt(0);
-                       if ((store.findExact('value', language) != -1) && (selectionEmpty || fullNodeSelected || !endPointsInSameBlock)) {
+                       if (language !== 'none' && (select.findValue(language) !== -1) && (selectionEmpty || fullNodeSelected || !endPointsInSameBlock)) {
+                               var text = this.localize('Remove language mark');
+                               select.setFirstOption(text, 'none', text);
                                select.setValue(language);
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('Remove language mark'),
-                                       value: 'none'
-                               }));
                        } else {
-                               store.insert(0, new store.recordType({
-                                       text: this.localize('No language mark'),
-                                       value: 'none'
-                               }));
+                               var text = this.localize('No language mark');
+                               select.setFirstOption(text, 'none', text);
                                select.setValue('none');
                        }
-                       select.setDisabled(!(store.getCount()>1) || (selectionEmpty && /^body$/i.test(this.editor.getSelection().getParentElement().nodeName)));
+                       select.setDisabled(!(select.getCount()>1) || (selectionEmpty && /^body$/i.test(this.editor.getSelection().getParentElement().nodeName)));
                }
        });
 
index 5e80bd9..bc8ad98 100644 (file)
@@ -53,7 +53,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                                        this.allowedAttributes.push('className');
                                }
                        }
-                       /*
+
+                       /**
                         * Registering plugin "About" information
                         */
                        var pluginInformation = {
@@ -66,20 +67,19 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                                license         : 'GPL'
                        };
                        this.registerPluginInformation(pluginInformation);
-                       /*
+
+                       /**
                         * Registering the dropdowns
                         */
                        var dropDown, buttonId;
                        for (var i = this.dropDownList.length; --i >= 0;) {
                                dropDown = this.dropDownList[i];
                                buttonId = dropDown[0];
-                               if (this.isButtonInToolbar(buttonId)) {
+                               if (this.isButtonInToolbar(buttonId) && this.buttonsConfiguration[dropDown[2]].dataUrl) {
                                        var dropDownConfiguration = {
                                                id: buttonId,
                                                tooltip: this.localize(buttonId.toLowerCase()),
-                                               storeUrl: this.buttonsConfiguration[dropDown[2]].dataUrl,
-                                               action: 'onChange',
-                                               tpl: this.disablePCexamples ? '' : '<tpl for="."><div title="{value}" style="' + dropDown[3] + '" class="x-combo-list-item">{text}</div></tpl>'
+                                               action: 'onChange'
                                        };
                                        if (this.buttonsConfiguration[dropDown[2]]) {
                                                if (this.editorConfiguration.buttons[dropDown[2]].width) {
@@ -97,52 +97,73 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                        }
                        return true;
                 },
-               /*
+
+               /**
                 * The list of buttons added by this plugin
                 */
                dropDownList: [
                        ['FontName', null, 'fontstyle', 'font-family:{value};text-align:left;font-size:11px;'],
                        ['FontSize', null, 'fontsize', 'text-align:left;font-size:{value};']
                ],
-               /*
+
+               /**
                 * Conversion object: button name to corresponding style property name
                 */
                styleProperty: {
                        FontName: 'fontFamily',
                        FontSize: 'fontSize'
                },
-               /*
+
+               /**
                 * Conversion object: button name to corresponding css property name
                 */
                cssProperty: {
                        FontName: 'font-family',
                        FontSize: 'font-size'
                },
+
                /**
                 * This funcion is invoked by the editor when it is being generated
                 */
                onGenerate: function () {
                        // Monitor the dropdowns stores being loaded
-                       var dropDown;
                        for (var i = this.dropDownList.length; --i >= 0;) {
-                               dropDown = this.dropDownList[i];
+                               var dropDown = this.dropDownList[i];
                                var select = this.getButton(dropDown[0]);
                                if (select) {
-                                       select.mon(select.getStore(), 'load', function () {
-                                               var selection = this.editor.getSelection(),
-                                                       selectionEmpty = selection.isEmpty(),
-                                                       ancestors = selection.getAllAncestors(),
-                                                       endPointsInSameBlock = selection.endPointsInSameBlock();
-                                               this.onUpdateToolbar(select, this.getEditorMode(), selectionEmpty, ancestors, endPointsInSameBlock);
-                                       }, this);
+                                       this.editor.ajax.getJavascriptFile(this.buttonsConfiguration[dropDown[2]].dataUrl, function (settings, success, response) {
+                                               if (success && response['responseJSON']) {
+                                                       for (var j = this.dropDownList.length; --j >= 0;) {
+                                                               var dropDown = this.dropDownList[j];
+                                                               if (settings['url'] === this.buttonsConfiguration[dropDown[2]].dataUrl) {
+                                                                       var options = response['responseJSON']['options'];
+                                                                       if (options) {
+                                                                               var select = this.getButton(dropDown[0]);
+                                                                               for (var k = 0, n = options.length; k < n; k++) {
+                                                                                       var title = options[k]['value'] === 'none' ? options[k]['text'] : options[k]['value'];
+                                                                                       var style = this.disablePCexamples ? '' : dropDown[3].replace(/\{value\}/g, options[k]['value']);
+                                                                                       select.addOption(options[k]['text'], options[k]['value'], title, style);
+                                                                               }
+                                                                               var selection = this.editor.getSelection(),
+                                                                                       selectionEmpty = selection.isEmpty(),
+                                                                                       ancestors = selection.getAllAncestors(),
+                                                                                       endPointsInSameBlock = selection.endPointsInSameBlock();
+                                                                               this.onUpdateToolbar(select, this.getEditorMode(), selectionEmpty, ancestors, endPointsInSameBlock);
+                                                                       }
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                       }, this, 'json');
                                }
                        }
                },
-               /*
+
+               /**
                 * This function gets called when some font style or font size was selected from the dropdown lists
                 */
-               onChange: function (editor, combo, record, index) {
-                       var param = combo.getValue();
+               onChange: function (editor, select) {
+                       var param = select.getValue();
                        var     element,
                                fullNodeSelected = false;
                        var range = editor.getSelection().createRange();
@@ -158,25 +179,25 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                        }
                        if (selectionEmpty || fullNodeSelected) {
                                element = parent;
-                                       // Set the style attribute
-                               this.setStyle(element, combo.itemId, param);
-                                       // Remove the span tag if it has no more attribute
+                               // Set the style attribute
+                               this.setStyle(element, select.itemId, param);
+                               // Remove the span tag if it has no more attribute
                                if (/^span$/i.test(element.nodeName) && !Dom.hasAllowedAttributes(element, this.allowedAttributes)) {
                                        editor.getDomNode().removeMarkup(element);
                                }
                        } else if (statusBarSelection) {
                                element = statusBarSelection;
-                                       // Set the style attribute
-                               this.setStyle(element, combo.itemId, param);
-                                       // Remove the span tag if it has no more attribute
+                               // Set the style attribute
+                               this.setStyle(element, select.itemId, param);
+                               // Remove the span tag if it has no more attribute
                                if (/^span$/i.test(element.nodeName) && !Dom.hasAllowedAttributes(element, this.allowedAttributes)) {
                                        editor.getDomNode().removeMarkup(element);
                                }
                        } else if (editor.getSelection().endPointsInSameBlock()) {
                                element = editor.document.createElement('span');
-                                       // Set the style attribute
-                               this.setStyle(element, combo.itemId, param);
-                                       // Wrap the selection with span tag with the style attribute
+                               // Set the style attribute
+                               this.setStyle(element, select.itemId, param);
+                               // Wrap the selection with span tag with the style attribute
                                editor.getDomNode().wrapWithInlineElement(element, range);
                                if (!UserAgent.isIEBeforeIE9) {
                                        range.detach();
@@ -184,7 +205,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                        }
                        return false;
                },
-               /*
+
+               /**
                 * This function sets the style attribute on the element
                 *
                 * @param       object  element: the element on which the style attribute is to be set
@@ -210,7 +232,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                                }
                        }
                },
-               /*
+
+               /**
                 * This function gets called when the toolbar is updated
                 */
                onUpdateToolbar: function (select, mode, selectionEmpty, ancestors, endPointsInSameBlock) {
@@ -228,18 +251,19 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                                                value = parentElement.currentStyle[this.styleProperty[select.itemId]];
                                        }
                                }
-                               var store = select.getStore();
                                var index = -1;
+                               var options = select.getOptions();
                                if (value) {
-                                       index = store.findBy(
-                                               function (record, id) {
-                                                       return record.get('value').replace(/[\"\']/g, '') == value.replace(/, /g, ',').replace(/[\"\']/g, '');
+                                       for (var i = 0, n = options.length; i < n; i++) {
+                                               if (options[i].value.replace(/[\"\']/g, '') === value.replace(/, /g, ',').replace(/[\"\']/g, '')) {
+                                                       index = i;
+                                                       break;
                                                }
-                                       );
+                                       }
                                }
-                               if (index != -1) {
-                                       select.setValue(store.getAt(index).get('value'));
-                               } else if (store.getCount()) {
+                               if (index !== -1) {
+                                       select.setValue(options[index].value);
+                               } else if (select.getCount()) {
                                        select.setValue('none');
                                }
                                select.setDisabled(!endPointsInSameBlock || (selectionEmpty && /^body$/i.test(parentElement.nodeName)));
index 1e060bd..492e70b 100644 (file)
@@ -39,16 +39,12 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                        this.tags = (this.pageTSconfiguration && this.pageTSconfiguration.tags) ? this.pageTSconfiguration.tags : {};
                        var allowedClasses;
                        for (var tagName in this.tags) {
-                               if (this.tags.hasOwnProperty(tagName)) {
-                                       if (this.tags[tagName].allowedClasses) {
-                                               allowedClasses = this.tags[tagName].allowedClasses.trim().split(",");
-                                               for (var cssClass in allowedClasses) {
-                                                       if (allowedClasses.hasOwnProperty(cssClass)) {
-                                                               allowedClasses[cssClass] = allowedClasses[cssClass].trim().replace(/\*/g, ".*");
-                                                       }
-                                               }
-                                               this.tags[tagName].allowedClasses = new RegExp( "^(" + allowedClasses.join("|") + ")$", "i");
+                               if (this.tags[tagName].allowedClasses) {
+                                       allowedClasses = this.tags[tagName].allowedClasses.trim().split(",");
+                                       for (var i = allowedClasses.length; --i >= 0;) {
+                                               allowedClasses[i] = allowedClasses[i].trim().replace(/\*/g, ".*");
                                        }
+                                       this.tags[tagName].allowedClasses = new RegExp( "^(" + allowedClasses.join("|") + ")$", "i");
                                }
                        }
                        this.showTagFreeClasses = this.pageTSconfiguration ? this.pageTSconfiguration.showTagFreeClasses : false;
@@ -77,7 +73,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                license         : 'GPL'
                        };
                        this.registerPluginInformation(pluginInformation);
-                       /*
+
+                       /**
                         * Registering the dropdown list
                         */
                        var buttonId = 'TextStyle';
@@ -90,9 +87,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                tooltip: this.localize(buttonId + '-Tooltip'),
                                fieldLabel: fieldLabel,
                                options: [[this.localize('No style'), 'none']],
-                               action: 'onChange',
-                               storeFields: [ { name: 'text'}, { name: 'value'}, { name: 'style'} ],
-                               tpl: '<tpl for="."><div title="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               action: 'onChange'
                        };
                        if (this.pageTSconfiguration) {
                                if (this.pageTSconfiguration.width) {
@@ -108,10 +103,18 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                        this.registerDropDown(dropDownConfiguration);
                        return true;
                },
+
+               /**
+                * Determine whether the element is an inline element
+                *
+                * @param object el: the element
+                * @return boolen true if the element is an inline element
+                */
                isInlineElement: function (el) {
                        return el && (el.nodeType === Dom.ELEMENT_NODE) && this.REInlineTags.test(el.nodeName.toLowerCase());
                },
-               /*
+
+               /**
                 * This function adds an attribute to the array of allowed attributes on inline elements
                 *
                 * @param       string  attribute: the name of the attribute to be added to the array
@@ -121,11 +124,12 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                addAllowedAttribute: function (attribute) {
                        this.allowedAttributes.push(attribute);
                },
-               /*
+
+               /**
                 * This function gets called when some style in the drop-down list applies it to the highlighted textt
                 */
-               onChange: function (editor, combo, record, index) {
-                       var className = combo.getValue();
+               onChange: function (editor, select) {
+                       var className = select.getValue();
                        var classNames = null;
                        var fullNodeSelected = false;
                        var statusBarSelection = this.editor.statusBar ? this.editor.statusBar.getSelection() : null;
@@ -154,7 +158,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                        }
                        if (!selectionEmpty && !fullNodeSelected || (!selectionEmpty && fullNodeSelected && parent && Dom.isBlockElement(parent))) {
                                        // The selection is not empty, nor full element, or the selection is full block element
-                               if (className !== "none") {
+                               if (className !== 'none') {
                                                // Add span element with class attribute
                                        var newElement = editor.document.createElement('span');
                                        Dom.addClass(newElement, className);
@@ -167,7 +171,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                this.applyClassChange(parent, className);
                        }
                },
-               /*
+
+               /**
                 * This function applies the class change to the node
                 *
                 * @param       object  node: the node on which to apply the class change
@@ -209,7 +214,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                tags: this.tags,
                                editor: this.editor
                        });
-                       // Disable the combo while initialization completes
+                       // Disable the dropdown while initialization completes
                        var dropDown = this.getButton('TextStyle');
                        if (dropDown) {
                                dropDown.setDisabled(true);
@@ -303,86 +308,161 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                }
                        }
                },
-               /*
+
+               /**
                 * This function reinitializes the options of the dropdown
                 */
                initializeDropDown: function (dropDown) {
-                       var store = dropDown.getStore();
-                       store.removeAll(false);
-                       store.insert(0, new store.recordType({
-                               text: this.localize('No style'),
-                               value: 'none'
-                       }));
-                       dropDown.setValue('none');
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       dropDown.removeAll();
+                                       dropDown.setFirstOption(this.localize('No style'), 'none', this.localize('No style'));
+                                       dropDown.setValue('none');
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       store.removeAll(false);
+                                       store.insert(0, new store.recordType({
+                                               text: this.localize('No style'),
+                                               value: 'none'
+                                       }));
+                                       dropDown.setValue('none');
+                       }
                },
-               /*
+
+               /**
                 * This function builds the options to be displayed in the dropDown box
                 */
                buildDropDownOptions: function (dropDown, nodeName) {
-                       var store = dropDown.getStore();
                        this.initializeDropDown(dropDown);
-                       if (this.textStyles.isReady()) {
-                               var allowedClasses = {};
-                               if (this.REInlineTags.test(nodeName)) {
-                                       if (typeof this.cssArray[nodeName] !== 'undefined') {
-                                               allowedClasses = this.cssArray[nodeName];
-                                       } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
-                                               allowedClasses = this.cssArray['all'];
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       if (this.textStyles.isReady()) {
+                                               var allowedClasses = {};
+                                               if (this.REInlineTags.test(nodeName)) {
+                                                       if (typeof this.cssArray[nodeName] !== 'undefined') {
+                                                               allowedClasses = this.cssArray[nodeName];
+                                                       } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
+                                                               allowedClasses = this.cssArray['all'];
+                                                       }
+                                               }
+                                               for (var cssClass in allowedClasses) {
+                                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                                               var style = (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null;
+                                                               dropDown.addOption(allowedClasses[cssClass], cssClass, cssClass, style);
+                                                       }
+                                               }
                                        }
-                               }
-                               for (var cssClass in allowedClasses) {
-                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
-                                               store.add(new store.recordType({
-                                                       text: allowedClasses[cssClass],
-                                                       value: cssClass,
-                                                       style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
-                                               }));
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       if (this.textStyles.isReady()) {
+                                               var allowedClasses = {};
+                                               if (this.REInlineTags.test(nodeName)) {
+                                                       if (typeof this.cssArray[nodeName] !== 'undefined') {
+                                                               allowedClasses = this.cssArray[nodeName];
+                                                       } else if (this.showTagFreeClasses && typeof this.cssArray['all'] !== 'undefined') {
+                                                               allowedClasses = this.cssArray['all'];
+                                                       }
+                                               }
+                                               for (var cssClass in allowedClasses) {
+                                                       if (typeof HTMLArea.classesSelectable[cssClass] === 'undefined' || HTMLArea.classesSelectable[cssClass]) {
+                                                               store.add(new store.recordType({
+                                                                       text: allowedClasses[cssClass],
+                                                                       value: cssClass,
+                                                                       style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[cssClass] && !HTMLArea.classesNoShow[cssClass]) ? HTMLArea.classesValues[cssClass] : null
+                                                               }));
+                                                       }
+                                               }
                                        }
-                               }
                        }
                },
-               /*
+
+               /**
                 * This function sets the selected option of the dropDown box
                 */
                setSelectedOption: function (dropDown, classNames, noUnknown, defaultClass) {
-                       var store = dropDown.getStore();
-                       dropDown.setValue('none');
-                       if (classNames.length) {
-                               var index = store.findExact('value', classNames[classNames.length-1]);
-                               if (index !== -1) {
-                                       dropDown.setValue(classNames[classNames.length-1]);
-                                       if (!defaultClass) {
-                                               store.getAt(0).set('text', this.localize('Remove style'));
-                                       }
-                               }
-                               if (index === -1 && !noUnknown) {
-                                       var text = this.localize('Unknown style');
-                                       var value = classNames[classNames.length-1];
-                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
-                                               text = HTMLArea.classesLabels[value];
-                                       }
-                                       store.add(new store.recordType({
-                                               text: text,
-                                               value: value,
-                                               style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
-                                       }));
-                                       dropDown.setValue(value);
-                                       if (!defaultClass) {
-                                               store.getAt(0).set('text', this.localize('Remove style'));
+                       switch (dropDown.xtype) {
+                               case 'htmlareaselect':
+                                       dropDown.setValue('none');
+                                       if (classNames.length) {
+                                               var index = dropDown.findValue(classNames[classNames.length-1]);
+                                               if (index !== -1) {
+                                                       dropDown.setValue(classNames[classNames.length-1]);
+                                                       if (!defaultClass) {
+                                                               var text = this.localize('Remove style');
+                                                               dropDown.setFirstOption(text, 'none', text);
+                                                       }
+                                               }
+                                               if (index === -1 && !noUnknown) {
+                                                       var text = this.localize('Unknown style');
+                                                       var value = classNames[classNames.length-1];
+                                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                                               text = HTMLArea.classesLabels[value];
+                                                       }
+                                                       var style = (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null;
+                                                       dropDown.addOption(text, value, value, style);
+                                                       dropDown.setValue(value);
+                                                       if (!defaultClass) {
+                                                               text = this.localize('Remove style');
+                                                               dropDown.setFirstOption(text, 'none', text);
+                                                       }
+                                               }
+                                               // Remove already assigned classes from the dropDown box
+                                               var selectedValue = dropDown.getValue();
+                                               for (var i = 0, n = classNames.length; i < n; i++) {
+                                                       index = dropDown.findValue(classNames[i]);
+                                                       if (index !== -1) {
+                                                               options = dropDown.getOptions();
+                                                               if (options[index].value !== selectedValue) {
+                                                                       dropDown.removeAt(index);
+                                                               }
+                                                       }
+                                               }
                                        }
-                               }
-                               // Remove already assigned classes from the dropDown box
-                               var classNamesString = ',' + classNames.join(',') + ',';
-                               var selectedValue = dropDown.getValue(), optionValue;
-                               store.each(function (option) {
-                                       optionValue = option.get('value');
-                                       if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
-                                               store.removeAt(store.indexOf(option));
+                                       dropDown.setDisabled(!dropDown.getCount() || (dropDown.getCount() === 1 && dropDown.getValue() === 'none'));
+                                       break;
+                               case 'combo':
+                                       var store = dropDown.getStore();
+                                       dropDown.setValue('none');
+                                       if (classNames.length) {
+                                               var index = store.findExact('value', classNames[classNames.length-1]);
+                                               if (index !== -1) {
+                                                       dropDown.setValue(classNames[classNames.length-1]);
+                                                       if (!defaultClass) {
+                                                               store.getAt(0).set('text', this.localize('Remove style'));
+                                                       }
+                                               }
+                                               if (index === -1 && !noUnknown) {
+                                                       var text = this.localize('Unknown style');
+                                                       var value = classNames[classNames.length-1];
+                                                       if (typeof HTMLArea.classesSelectable[value] !== 'undefined' && !HTMLArea.classesSelectable[value] && typeof HTMLArea.classesLabels[value] !== 'undefined') {
+                                                               text = HTMLArea.classesLabels[value];
+                                                       }
+                                                       store.add(new store.recordType({
+                                                               text: text,
+                                                               value: value,
+                                                               style: (!(this.pageTSconfiguration && this.pageTSconfiguration.disableStyleOnOptionLabel) && HTMLArea.classesValues && HTMLArea.classesValues[value] && !HTMLArea.classesNoShow[value]) ? HTMLArea.classesValues[value] : null
+                                                       }));
+                                                       dropDown.setValue(value);
+                                                       if (!defaultClass) {
+                                                               store.getAt(0).set('text', this.localize('Remove style'));
+                                                       }
+                                               }
+                                               // Remove already assigned classes from the dropDown box
+                                               var classNamesString = ',' + classNames.join(',') + ',';
+                                               var selectedValue = dropDown.getValue(), optionValue;
+                                               store.each(function (option) {
+                                                       optionValue = option.get('value');
+                                                       if (classNamesString.indexOf(',' + optionValue + ',') !== -1 && optionValue !== selectedValue) {
+                                                               store.removeAt(store.indexOf(option));
+                                                       }
+                                                       return true;
+                                               });
                                        }
-                                       return true;
-                               });
+                                       dropDown.setDisabled(!store.getCount() || (store.getCount() == 1 && dropDown.getValue() == 'none'));
+                                       break;
                        }
-                       dropDown.setDisabled(!store.getCount() || (store.getCount() == 1 && dropDown.getValue() == 'none'));
                },
 
                /**
@@ -396,8 +476,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                if (classNames.length && (selectionEmpty || fullNodeSelected)) {
                                        this.setSelectedOption(dropDown, classNames);
                                }
-                               var store = dropDown.getStore();
-                               dropDown.setDisabled(!store.getCount() || (store.getCount() == 1 && dropDown.getValue() == 'none') || disabled);
+                               dropDown.setDisabled(!dropDown.getCount() || (dropDown.getCount() === 1 && dropDown.getValue() === 'none') || disabled);
                        }
                }
        });
index 59cb96f..001970e 100644 (file)
        overflow: hidden;
 }
 .htmlarea .toolbar .select {
-       color: WindowText;
        height: 17px;
 }
+.htmlarea .toolbar select {
+       border: 1px solid #c7c7c7;
+       border-radius: 2px;
+       display: inline-block;
+       height: 22px !important;
+       margin: 0 0 4px 0;
+       padding: 2px 1px;
+}
+.htmlarea .toolbar select option {
+       padding: 2px;
+}
 .htmlarea .toolbar .x-form-field-wrap .x-form-trigger {
        right: 0;
 }