[TASK] RTE: Migrate the editor toolbar to plain JavaScript 87/35487/4
authorStanislas Rolland <typo3@sjbr.ca>
Mon, 15 Dec 2014 17:34:44 +0000 (12:34 -0500)
committerStanislas Rolland <typo3@sjbr.ca>
Tue, 16 Dec 2014 17:02:03 +0000 (18:02 +0100)
The toolbar container is plain JavaScript but the buttons, combos and
other widgets are still ExtJS objects.

Releases: master
Resolves: #63794
Change-Id: Ib88431a1c1463f75fc05ec12c5a30d274dc2212a
Reviewed-on: http://review.typo3.org/35487
Reviewed-by: Stanislas Rolland <typo3@sjbr.ca>
Tested-by: Stanislas Rolland <typo3@sjbr.ca>
23 files changed:
typo3/sysext/rtehtmlarea/Resources/Public/Css/Skin/htmlarea.css
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/Iframe.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/StatusBar.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/TextAreaContainer.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Editor/Toolbar.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/Button.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/Combo.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/HTMLArea/Extjs/ux/ToolbarText.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/Abbreviation.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/BlockStyle.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/ContextMenu.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultImage.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/DefaultLink.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/SelectFont.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TYPO3Image.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TYPO3Link.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TableOperations.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TextIndicator.js
typo3/sysext/rtehtmlarea/Resources/Public/JavaScript/Plugins/TextStyle.js
typo3/sysext/t3skin/rtehtmlarea/htmlarea.css

index 3769af4..f85abe3 100644 (file)
        height: 26px;
        margin: 0 2px;
 }
-.htmlarea .toolbar .x-form-item-label {
-       border-style: none;
-       background-color: transparent;
-       margin: 0;
-       min-width: 110px;
-       padding: 3px 3px 0px 3px;
-       vertical-align: middle;
+.htmlarea .toolbar .toolbar-text .x-form-item-label {
+       display: block;
+       font-weight: normal;
+       width: auto;
 }
 .htmlarea .toolbar .button {
        background-color: transparent;
        margin: 0 0 3px 0;
        padding: 0;
 }
-.htmlarea .toolbar .x-btn-mc {
-       background-color: transparent;
-       background-image: none;
-       border-style: none;
-       margin: 0;
-       padding: 0;
-}
-.htmlarea .toolbar .x-btn-tl,
-.htmlarea .toolbar .x-btn-tc,
-.htmlarea .toolbar .x-btn-tr,
-.htmlarea .toolbar .x-btn-ml,
-.htmlarea .toolbar .x-btn-mr,
-.htmlarea .toolbar .x-btn-bl,
-.htmlarea .toolbar .x-btn-bc,
-.htmlarea .toolbar .x-btn-br {
-       display: none;
-}
 .htmlarea .toolbar .x-btn-text {
        background-image: url("../../Images/Sprites/actions.png");
        background-repeat: no-repeat;
        height: 18px;
        overflow: hidden;
        margin: 3px 1px 5px 1px;
+       padding: 0 2px 4px 0;
        text-align: center;
        width: 24px;
 }
        width: 1px;
 }
 .htmlarea .toolbar .space {
-       height:22px;
-       border-style:none;
-       margin:0;padding:0 1px;
-       float:left;
+       background-color: transparent;
+       border-style: none;
+       float: left;
+       height: 22px;
+       margin: 0;
+       padding: 0 1px;
+       width: 2px;
+}
+.htmlarea .toolbar .space-clear-left {
+       clear: left;
+       font-size: 0;
+       height: 0;
+       line-height: 0;
+       overflow: hidden;
 }
 .htmlarea .toolbar .select {
        height: 17px;
 }
-.htmlarea .toolbar .x-form-item label.x-form-item-label {
-       padding-right: 0;
-}
 .htmlarea .toolbar .x-form-field-wrap .x-form-trigger {
        right: 0;
 }
index 777e1b1..de4f68a 100644 (file)
@@ -106,7 +106,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Configuration/Config',
                                displayField: 'text',
                                labelSeparator: '',
                                hideLabel: true,
-                               tpl: '<tpl for="."><div ext:qtip="{value}" style="text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               tpl: '<tpl for="."><div title="{value}" style="text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
                        }
                };
        };
@@ -166,7 +166,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Configuration/Config',
                                break;
                }
                config.cmd = config.id;
-               config.tooltip = { title: config.tooltip };
+               config.tooltipType = 'title';
                this.buttonsConfig[config.id] = config;
                return true;
        };
index dfe8a53..a3cb9f8 100644 (file)
@@ -192,13 +192,12 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                        maxHeight: this.config.maxHeight,
                        isNested: this.isNested,
                        nestedParentElements: this.nestedParentElements,
-                       items: [new Toolbar ({
-                               // The toolbar
-                               id: this.editorId + '-toolbar',
-                               itemId: 'toolbar',
-                               layout: 'form',
-                               cls: 'toolbar',
-                               editorId: this.editorId
+                       items: [new Toolbar({
+                                       // The toolbar
+                                       id: this.editorId + '-toolbar',
+                                       itemId: 'toolbar',
+                                       cls: 'toolbar',
+                                       editorId: this.editorId
                                }),
                                new Iframe({
                                        // The iframe
@@ -572,6 +571,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Editor',
                        this.unRegisterPlugin(pluginId);
                }
                Event.off(this.textarea);
+               this.htmlArea.onBeforeDestroy();
                RTEarea[this.editorId].editor = null;
                return true;
        };
index 072b375..1fcd90b 100644 (file)
@@ -19,11 +19,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/Resizable',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/DOM/DOM',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Util/TYPO3',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
-       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar'],
-       function (Util, Resizable, Dom, Typo3, Event, Toolbar, Iframe, Statusbar) {
+       'TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event'],
+       function (Util, Resizable, Dom, Typo3, Event) {
 
        /**
         * Framework constructor
@@ -107,8 +104,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                                }
                                Event.on(form, 'reset', function (event) { return self.onReset(event); });
                        }
-                       // Monitor editor being unloaded
-                       Event.one(this.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
                },
 
                /**
@@ -286,7 +281,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                        if (this.getInnerHeight() <= 0) {
                                this.onWindowResize();
                        } else {
-                               //this.iframe.setHeight(this.getInnerHeight());
                                Dom.setSize(this.iframe.getEl(), { height: this.getInnerHeight()});
                                Dom.setSize(this.textArea, { height: this.getInnerHeight()});
                        }
@@ -363,8 +357,12 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Framework',
                        if (this.resizer) {
                                Resizable.destroy(this.resizer);
                        }
+                       for (var i = 0, n = this.items.length; i < n; i++) {
+                               if (typeof this.items[i].onBeforeDestroy === 'function') {
+                                       this.items[i].onBeforeDestroy();
+                               }
+                       }
                        this.el = null;
-                       return true;
                }
        };
 
index e7865d7..d4a740f 100644 (file)
@@ -65,11 +65,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                 * Initialize event listeners and the document after the iframe has rendered
                 */
                initEventListeners: function () {
-                       var self = this;
                        this.initStyleChangeEventListener();
-                       // Monitor editor becoming ready
-                       var self = this;
-                       Event.one(this.getEditor(), 'HtmlAreaEventEditorReady', function (event) { Event.stopEvent(event); self.onEditorReady(); return false; });
                        if (UserAgent.isOpera) {
                                var self = this;
                                Event.one(iframe, 'load', function (event) { self.initializeIframe(event); return true; })
@@ -763,16 +759,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                },
 
                /**
-                * When the editor becomes ready
-                */
-               onEditorReady: function () {
-                       var self = this;
-                       // Monitor editor being unloaded
-                       Event.one(this.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
-               },
-
-               /**
-                * Cleanup
+                * Cleanup (called by framework)
                 */
                onBeforeDestroy: function () {
                        // Remove listeners on nested elements
@@ -789,10 +776,8 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Iframe',
                        Event.off(this.document.documentElement);
                        // Cleaning references to DOM in order to avoid IE memory leaks
                        this.document = null;
-                       this.getEditor().document = null;
                        this.el = null;
                        delete this.el;
-                       return true;
                }
        };
 
index a7e6f92..2732a13 100644 (file)
@@ -62,8 +62,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                        Event.on(this.getEditor(), 'HTMLAreaEventModeChange', function (event, mode) { Event.stopEvent(event); self.onModeChange(mode); return false; });
                        // Monitor word count change
                        Event.on(this.framework.iframe, 'HTMLAreaEventWordCountChange', function (event, delay) { Event.stopEvent(event); self.onWordCountChange(delay); return false; });
-                       // Monitor editor being unloaded
-                       Event.one(this.framework.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
                },
 
                /**
@@ -335,7 +333,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                },
 
                /**
-                * Cleanup
+                * Cleanup (called by framework)
                 */
                onBeforeDestroy: function() {
                        this.clear();
@@ -346,7 +344,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/StatusBar',
                        this.statusBarWordCount = null;
                        this.el = null;
                        delete this.el;
-                       return true;
                }
        };
 
index 7a2923d..588502f 100644 (file)
@@ -46,16 +46,6 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/TextAreaContainer',
                        this.el = container.appendChild(this.el);
                        this.swallow(this.textArea);
                        this.rendered = true;
-                       this.initEventListeners();
-               },
-
-               /**
-                * Initialize listeners (after rendering)
-                */
-               initEventListeners: function () {
-                       var self = this;
-                       // Monitor editor being unloaded
-                       Event.one(this.framework.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
                },
 
                /**
@@ -101,12 +91,11 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/TextAreaContainer',
                },
 
                /**
-                * Throw back the texarea
+                * Throw back the texarea (called by framework)
                 */
                onBeforeDestroy: function() {
                        this.originalParent.appendChild(this.textArea);
                        Event.off(this);
-                       return true;
                }
        };
 
index bf85907..41d4dc6 100644 (file)
  */
 
 /**
- * HTMLArea.Toolbar extends Ext.Container
+ * The editor toolbar
  */
 define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
-       ['TYPO3/CMS/Rtehtmlarea/HTMLArea/Event/Event',
+       ['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/Extjs/ux/Button',
        'TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/ToolbarText'],
-       function (Event, Combo, Button, ToolbarText) {
+       function (Util, Dom, Event, Combo, Button, ToolbarText) {
 
-       var Toolbar = Ext.extend(Ext.Container, {
+       /**
+        * Editor toolbar constructor
+        */
+       var Toolbar = function (config) {
+               Util.apply(this, config);
+       };
+
+       Toolbar.prototype = {
 
                /**
-                * Constructor
+                * Render the toolbar (called by framework rendering)
+                *
+                * @param object container: the container into which to insert the toolbar (that is the framework)
+                * @return void
                 */
-               initComponent: function () {
-                       Toolbar.superclass.initComponent.call(this);
-                       // Add the toolbar items
+               render: function (container) {
+                       this.el = document.createElement('div');
+                       if (this.id) {
+                               this.el.setAttribute('id', this.id);
+                       }
+                       if (this.cls) {
+                               this.el.setAttribute('class', this.cls);
+                       }
+                       this.el = container.appendChild(this.el);
                        this.addItems();
-                       this.addListener({
-                               afterrender: {
-                                       fn: this.initEventListeners,
-                                       single: true
-                               }
-                       });
+                       this.rendered = true;
                },
 
                /**
-                * Initialize listeners
+                * Get the element to which the toolbar is rendered
                 */
-               initEventListeners: function () {
-                       // Monitor editor becoming ready
-                       var self = this;
-                       Event.one(this.getEditor(), 'HtmlAreaEventEditorReady', function (event) { Event.stopEvent(event); self.onEditorReady(); return false; });
+               getEl: function () {
+                       return this.el;
                },
 
                /**
@@ -60,6 +71,11 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                },
 
                /**
+                * The toolbar items
+                */
+               items: {},
+
+               /**
                 * Create the toolbar items based on editor toolbar configuration
                 */
                addItems: function () {
@@ -72,10 +88,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                                row = editor.config.toolbar[i];
                                if (!firstOnRow) {
                                        // If a visible item was added to the previous line
-                                       this.add({
-                                               xtype: 'tbspacer',
-                                               cls: 'x-form-clear-left'
-                                       });
+                                       this.addSpacer('space-clear-left');
                                }
                                firstOnRow = true;
                                // Add the groups
@@ -84,25 +97,20 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                                        // To do: this.config.keepButtonGroupTogether ...
                                        if (!firstOnRow && !firstInGroup) {
                                                // If a visible item was added to the line
-                                               this.add({
-                                                       xtype: 'tbseparator',
-                                                       cls: 'separator'
-                                               });
+                                               this.addSeparator();
                                        }
                                        firstInGroup = true;
                                        // Add each item
                                        for (k = 0, p = group.length; k < p; k++) {
                                                item = group[k];
                                                if (item == 'space') {
-                                                       this.add({
-                                                               xtype: 'tbspacer',
-                                                               cls: 'space'
-                                                       });
+                                                       this.addSpacer();
                                                } else {
                                                        // Get the item's config as registered by some plugin
                                                        var itemConfig = editor.config.buttonsConfig[item];
                                                        if (typeof itemConfig === 'object' && itemConfig !== null) {
                                                                itemConfig.id = this.editorId + '-' + itemConfig.id;
+                                                               itemConfig.toolbar = this;
                                                                switch (itemConfig.xtype) {
                                                                        case 'htmlareabutton':
                                                                                this.add(new Button(itemConfig));
@@ -123,17 +131,106 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                                        }
                                }
                        }
-                       this.add({
-                               xtype: 'tbspacer',
-                               cls: 'x-form-clear-left'
-                       });
+                       this.addSpacer('space-clear-left');
+               },
+
+               /**
+                * Add an item to the toolbar
+                *
+                * @param object item: the item to be added (not yet rendered)
+                * @return void
+                */
+               add: function (item) {
+                       if (item.xtype === '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');
+                                       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);
+                               }
+                       } else {
+                               item.render(this.el);
+                               var itemDiv = this.el.appendChild(item.getEl().dom);
+                               Dom.addClass(item.getEl().dom, 'x-form-item');
+                       }
+                       if (item.xtype === 'htmlareatoolbartext') {
+                               Dom.addClass(item.getEl().dom, 'x-form-item-label');
+                       }
+                       if (item.itemId) {
+                               this.items[item.itemId] = item;
+                       }
+               },
+
+               /**
+                * Add a spacer to the toolbar
+                *
+                * @param string cls: a class to be added on the spacer
+                * @return void
+                */
+               addSpacer: function (cls) {
+                       var spacer = document.createElement('div');
+                       Dom.addClass(spacer, 'space');
+                       if (typeof cls === 'string') {
+                               Dom.addClass(spacer, cls);
+                       }
+                       this.el.appendChild(spacer);
+               },
+
+               /**
+                * Add a separator to the toolbar
+                *
+                * @param string cls: a class to be added on the separator
+                * @return void
+                */
+               addSeparator: function (cls) {
+                       var spacer = document.createElement('div');
+                       Dom.addClass(spacer, 'separator');
+                       if (typeof cls === 'string') {
+                               Dom.addClass(spacer, cls);
+                       }
+                       this.el.appendChild(spacer);
+               },
+
+               /**
+                * Remove a button from the toolbar
+                *
+                * @param string buttonId: the itemId of the item to remove
+                * @return void
+                */
+               remove: function (buttonId) {
+                       var item = this.items[buttonId];
+                       if (item) {
+                               if (item.getEl()) {
+                                       Dom.removeFromParent(item.getEl().dom);
+                               }
+                               this.items[item.itemId] = null;
+                       }
                },
 
                /**
                 * Retrieve a toolbar item by itemId
                 */
                getButton: function (buttonId) {
-                       return this.find('itemId', buttonId)[0];
+                       return this.items[buttonId];
+               },
+
+               /**
+                * Get the current height of the toolbar
+                */
+               getHeight: function () {
+                       return Dom.getSize(this.el).height;
                },
 
                /**
@@ -176,24 +273,22 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Editor/Toolbar',
                },
 
                /**
-                * When the editor becomes ready
-                */
-               onEditorReady: function () {
-                       var self = this;
-                       // Monitor editor being unloaded
-                       Event.one(this.framework.iframe.getIframeWindow(), 'unload', function (event) { return self.onBeforeDestroy(); });
-                       this.update();
-               },
-
-               /**
-                * Cleanup
+                * Cleanup (called by framework onBeforeDestroy)
                 */
                onBeforeDestroy: function () {
                        Event.off(this);
-                       this.removeAll(true);
-                       return true;
+                       while (node = this.el.firstChild) {
+                               this.el.removeChild(node);
+                       }
+                       for (var itemId in this.items) {
+                               if (typeof this.items[itemId].destroy === 'function') {
+                                       try {
+                                               this.items[itemId].destroy();
+                                       } catch (e) {}
+                               }
+                       }
                }
-       });
+       };
 
        return Toolbar;
 
index 1045a1b..c42099f 100644 (file)
@@ -25,6 +25,11 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Button',
                 * Component initialization
                 */
                initComponent: function () {
+                       this.template = new Ext.Template(
+                               '<div id="{4}" class="x-btn {3}">',
+                               '<em class="{2} x-unselectable" unselectable="on"><button type="{0}"></button></em>',
+                               '</div>');
+                       this.template.compile();
                        Button.superclass.initComponent.call(this);
                        this.addListener({
                                afterrender: {
@@ -50,14 +55,14 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Button',
                 * Get a reference to the editor
                 */
                getEditor: function() {
-                       return RTEarea[this.ownerCt.editorId].editor;
+                       return RTEarea[this.toolbar.editorId].editor;
                },
 
                /**
                 * Get a reference to the toolbar
                 */
                getToolbar: function() {
-                       return this.ownerCt;
+                       return this.toolbar;
                },
 
                /**
@@ -145,6 +150,14 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Button',
                                }
                                this.plugins['onUpdateToolbar'](this, mode, selectionEmpty, ancestors, endPointsInSameBlock);
                        }
+               },
+
+               /**
+                * Update the tooltip text
+                */
+               setTooltip: function (text) {
+                       this.tooltip = text;
+                       this.getEl().dom.firstChild.firstChild.title = text;
                }
        });
 
index 399d5e7..c036541 100644 (file)
@@ -16,8 +16,9 @@
  */
 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, Event) {
+       function (UserAgent, Dom, Event) {
 
        var Combo = Ext.extend(Ext.form.ComboBox, {
 
@@ -27,6 +28,7 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
                initComponent: function () {
                        this.superClass = Combo.superclass;
                        this.superClass.initComponent.call(this);
+                       this.isFirstExpand = true;
                        this.addListener({
                                afterrender: {
                                        fn: this.initEventListeners,
@@ -56,21 +58,21 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
                        // 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().ownerCt, 'HTMLAreaEventFrameworkReady', function (event) { Event.stopEvent(event); self.onFrameworkReady(); return false; });
+                       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.ownerCt.editorId].editor;
+                       return RTEarea[this.toolbar.editorId].editor;
                },
 
                /**
                 * Get a reference to the toolbar
                 */
                getToolbar: function() {
-                       return this.ownerCt;
+                       return this.toolbar;
                },
 
                /**
@@ -107,6 +109,12 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
                 */
                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;
@@ -115,6 +123,24 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
                },
 
                /**
+                * 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) {
@@ -188,9 +214,9 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/Combo',
                        // 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().dom, 'mouseleave', function (event) { self.saveSelection(event); return true; });
+                               Event.on(iframe.getEl(), 'mouseleave', function (event) { self.saveSelection(event); return true; });
                                // Restore the selection if combo was triggered
-                               Event.on(iframe.getEl().dom, 'focus', function (event) { self.restoreSelection(event); return true; });
+                               Event.on(iframe.getEl(), 'focus', function (event) { self.restoreSelection(event); return true; });
                        }
                },
 
index 58336f3..0fe4321 100644 (file)
@@ -46,14 +46,14 @@ define('TYPO3/CMS/Rtehtmlarea/HTMLArea/Extjs/ux/ToolbarText',
                 * Get a reference to the editor
                 */
                getEditor: function() {
-                       return RTEarea[this.ownerCt.editorId].editor;
+                       return RTEarea[this.toolbar.editorId].editor;
                },
 
                /**
                 * Get a reference to the toolbar
                 */
                getToolbar: function() {
-                       return this.ownerCt;
+                       return this.toolbar;
                },
 
                /**
index 90d323a..e2a46ea 100644 (file)
@@ -100,7 +100,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Abbreviation',
                        };
                                // Open the dialogue window
                        this.openDialogue(
-                               this.getButton(buttonId).tooltip.title,
+                               this.getButton(buttonId).tooltip,
                                buttonId,
                                this.getWindowDimensions({ width: 580}, buttonId),
                                this.buildTabItemsConfig(abbr),
@@ -540,7 +540,8 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Abbreviation',
                        this.close();
                        event.stopEvent();
                },
-               /*
+
+               /**
                 * This function gets called when the toolbar is updated
                 */
                onUpdateToolbar: function (button, mode, selectionEmpty, ancestors) {
@@ -550,9 +551,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/Abbreviation',
                                        button.setDisabled(((el.nodeName.toLowerCase() == 'acronym' && this.pageTSConfiguration.noAcronym) || (el.nodeName.toLowerCase() == 'abbr' && this.pageTSConfiguration.noAbbr)));
                                        button.setInactive(!(el.nodeName.toLowerCase() == 'acronym' && !this.pageTSConfiguration.noAcronym) && !(el.nodeName.toLowerCase() == 'abbr' && !this.pageTSConfiguration.noAbbr));
                                }
-                               button.setTooltip({
-                                       title: this.localize((button.disabled || button.inactive) ? 'Insert abbreviation' : 'Edit abbreviation')
-                               });
+                               button.setTooltip(this.localize((button.disabled || button.inactive) ? 'Insert abbreviation' : 'Edit abbreviation'));
                                button.contextMenuTitle = '';
                                if (this.dialog) {
                                        this.dialog.focus();
index 2d9e484..42eff16 100644 (file)
@@ -81,7 +81,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/BlockStyle',
                                options: [[this.localize('No style'), 'none']],
                                action: 'onChange',
                                storeFields: [ { name: 'text'}, { name: 'value'}, { name: 'style'} ],
-                               tpl: '<tpl for="."><div ext:qtip="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               tpl: '<tpl for="."><div title="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
                        };
                        if (this.pageTSconfiguration) {
                                if (this.pageTSconfiguration.width) {
index b0354dd..50469c1 100644 (file)
@@ -125,7 +125,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/ContextMenu',
                                                                        itemId: itemId,
                                                                        cls: 'button',
                                                                        overCls: 'hover',
-                                                                       text: (button.contextMenuTitle ? button.contextMenuTitle : button.tooltip.title),
+                                                                       text: (button.contextMenuTitle ? button.contextMenuTitle : button.tooltip),
                                                                        iconCls: button.iconCls,
                                                                        helpText: (button.helpText ? button.helpText : this.localize(itemId + '-tooltip')),
                                                                        hidden: true
@@ -211,7 +211,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/ContextMenu',
                                } else if (xtype === 'menuitem') {
                                        var button = this.getButton(menuItem.getItemId());
                                        if (button) {
-                                               var text = button.contextMenuTitle ? button.contextMenuTitle : button.tooltip.title;
+                                               var text = button.contextMenuTitle ? button.contextMenuTitle : button.tooltip;
                                                if (menuItem.text != text) {
                                                        menuItem.setText(text);
                                                }
index e23e6cb..b8a6ac3 100644 (file)
@@ -146,7 +146,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultImage',
                                // Open dialogue window
                        this.openDialogue(
                                buttonId,
-                               this.getButton(buttonId).tooltip.title,
+                               this.getButton(buttonId).tooltip,
                                this.getWindowDimensions(
                                        {
                                                width: 460,
@@ -516,9 +516,9 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultImage',
                                        image = null;
                                }
                                if (image) {
-                                       button.setTooltip({ title: this.localize('Modify image') });
+                                       button.setTooltip(this.localize('Modify image'));
                                } else {
-                                       button.setTooltip({ title: this.localize('Insert image') });
+                                       button.setTooltip(this.localize('Insert image'));
                                }
                        }
                }
index 9d8eb4f..7056427 100644 (file)
@@ -126,7 +126,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink',
                                        if (!this.link) {
                                                if (this.editor.getSelection().isEmpty()) {
                                                        TYPO3.Dialog.InformationDialog({
-                                                               title: this.getButton(buttonId).tooltip.title,
+                                                               title: this.getButton(buttonId).tooltip,
                                                                msg: this.localize('Select some text')
                                                        });
                                                        break;
@@ -146,7 +146,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink',
                                                // Open dialogue window
                                        this.openDialogue(
                                                buttonId,
-                                               this.getButton(buttonId).tooltip.title,
+                                               this.getButton(buttonId).tooltip,
                                                this.getWindowDimensions(
                                                        {
                                                                width: 470,
@@ -389,9 +389,9 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/DefaultLink',
                                                                node = el;
                                                        }
                                                        if (node != null && /^a$/i.test(node.nodeName)) {
-                                                               button.setTooltip({ title: this.localize('Modify link') });
+                                                               button.setTooltip(this.localize('Modify link'));
                                                        } else {
-                                                               button.setTooltip({ title: this.localize('Insert link') });
+                                                               button.setTooltip(this.localize('Insert link'));
                                                        }
                                                }
                                                break;
index a9696a7..5e80bd9 100644 (file)
@@ -79,7 +79,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/SelectFont',
                                                tooltip: this.localize(buttonId.toLowerCase()),
                                                storeUrl: this.buttonsConfiguration[dropDown[2]].dataUrl,
                                                action: 'onChange',
-                                               tpl: this.disablePCexamples ? '' : '<tpl for="."><div ext:qtip="{value}" style="' + dropDown[3] + '" class="x-combo-list-item">{text}</div></tpl>'
+                                               tpl: this.disablePCexamples ? '' : '<tpl for="."><div title="{value}" style="' + dropDown[3] + '" class="x-combo-list-item">{text}</div></tpl>'
                                        };
                                        if (this.buttonsConfiguration[dropDown[2]]) {
                                                if (this.editorConfiguration.buttons[dropDown[2]].width) {
index cdf2da2..4bff4a0 100644 (file)
@@ -86,7 +86,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TYPO3Image',
                        }
                        this.openContainerWindow(
                                buttonId,
-                               this.getButton(buttonId).tooltip.title,
+                               this.getButton(buttonId).tooltip,
                                this.getWindowDimensions(
                                        {
                                                width:  650,
@@ -139,9 +139,9 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TYPO3Image',
                                        image = null;
                                }
                                if (image) {
-                                       button.setTooltip({ title: this.localize('Modify image') });
+                                       button.setTooltip(this.localize('Modify image'));
                                } else {
-                                       button.setTooltip({ title: this.localize('Insert image') });
+                                       button.setTooltip(this.localize('Insert image'));
                                }
                        }
                }
index 79c3cda..7b83071 100644 (file)
@@ -161,7 +161,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TYPO3Link',
                                }
                                this.openContainerWindow(
                                        buttonId,
-                                       this.getButton(buttonId).tooltip.title,
+                                       this.getButton(buttonId).tooltip,
                                        this.getWindowDimensions(
                                                {
                                                        width:  550,
@@ -463,9 +463,9 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TYPO3Link',
                                                                node = el;
                                                        }
                                                        if (node != null && /^a$/i.test(node.nodeName)) {
-                                                               button.setTooltip({ title: this.localize('Modify link') });
+                                                               button.setTooltip(this.localize('Modify link'));
                                                        } else {
-                                                               button.setTooltip({ title: this.localize('Insert link') });
+                                                               button.setTooltip(this.localize('Insert link'));
                                                        }
                                                }
                                                break;
index aead885..ca51136 100644 (file)
@@ -368,7 +368,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TableOperations',
                                if (this.properties.required.indexOf('captionOrSummary') != -1) {
                                        if (!/\S/.test(params.f_caption) && !/\S/.test(params.f_summary)) {
                                                TYPO3.Dialog.ErrorDialog({
-                                                       title: this.getButton(this.dialog.arguments.buttonId).tooltip.title,
+                                                       title: this.getButton(this.dialog.arguments.buttonId).tooltip,
                                                        msg: this.localize('captionOrSummary' + '-required')
                                                });
                                                var field = this.dialog.find('itemId', 'f_caption')[0];
@@ -385,7 +385,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TableOperations',
                                        for (var item in required) {
                                                if (!params[item] && this.properties.required.indexOf(required[item]) != -1) {
                                                        TYPO3.Dialog.ErrorDialog({
-                                                               title: this.getButton(this.dialog.arguments.buttonId).tooltip.title,
+                                                               title: this.getButton(this.dialog.arguments.buttonId).tooltip,
                                                                msg: this.localize(required[item] + '-required')
                                                        });
                                                        var field = this.dialog.find('itemId', item)[0];
@@ -410,7 +410,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TableOperations',
                                for (var item in required) {
                                        if (!params[item]) {
                                                TYPO3.Dialog.ErrorDialog({
-                                                       title: this.getButton(this.dialog.arguments.buttonId).tooltip.title,
+                                                       title: this.getButton(this.dialog.arguments.buttonId).tooltip,
                                                        msg: this.localize(required[item])
                                                });
                                                var field = this.dialog.find('itemId', item)[0];
@@ -1030,7 +1030,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TableOperations',
                                        var cell = this.editor.getSelection().getFirstAncestorOfType(['td', 'th']);
                                        if (!cell) {
                                                TYPO3.Dialog.InformationDialog({
-                                                       title: this.getButton('TO-cell-merge').tooltip.title,
+                                                       title: this.getButton('TO-cell-merge').tooltip,
                                                        msg: this.localize('Please click into some cell')
                                                });
                                                break;
index b2ad563..b23d425 100644 (file)
@@ -130,6 +130,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextIndicator',
                                        style.fontStyle = 'normal';
                                }
                                button.getEl().setStyle(style);
+                               button.getEl().dom.setAttribute('title', button.tooltip);
                        }
                }
        });
index 198de2d..1e060bd 100644 (file)
@@ -92,7 +92,7 @@ define('TYPO3/CMS/Rtehtmlarea/Plugins/TextStyle',
                                options: [[this.localize('No style'), 'none']],
                                action: 'onChange',
                                storeFields: [ { name: 'text'}, { name: 'value'}, { name: 'style'} ],
-                               tpl: '<tpl for="."><div ext:qtip="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
+                               tpl: '<tpl for="."><div title="{value}" style="{style}text-align:left;font-size:11px;" class="x-combo-list-item">{text}</div></tpl>'
                        };
                        if (this.pageTSconfiguration) {
                                if (this.pageTSconfiguration.width) {
index 2646bf4..af04125 100644 (file)
        height: 26px;
        margin: 0 2px;
 }
-.htmlarea .toolbar .x-form-item-label {
-       vertical-align:middle;
-       background-color:transparent;
-       border-style:none;
-       margin:0;
-       padding:2px 3px 0px 3px;
-       min-width: 110px;
+.htmlarea .toolbar .toolbar-text .x-form-item-label {
+       display: block;
+       font-weight: normal;
+       width: auto;
 }
 .htmlarea .toolbar .button {
        background-color: transparent;
        padding: 0;
        float: left;
 }
-.htmlarea .toolbar .x-btn-mc {
-       background-color: transparent;
-       background-image: none;
-       border-style: none;
-       margin: 0;
-       padding: 0;
-}
-.htmlarea .toolbar .x-btn-tl,
-.htmlarea .toolbar .x-btn-tc,
-.htmlarea .toolbar .x-btn-tr,
-.htmlarea .toolbar .x-btn-ml,
-.htmlarea .toolbar .x-btn-mr,
-.htmlarea .toolbar .x-btn-bl,
-.htmlarea .toolbar .x-btn-bc,
-.htmlarea .toolbar .x-btn-br {
-       display: none;
-}
 .htmlarea .toolbar .x-btn-text {
        background-image: url("images/sprites/actions.png");
        background-repeat: no-repeat;
        opacity: 1.00;
 }
 .htmlarea .toolbar .indicator {
-       cursor: default;
        background-color: white;
-       width: 24px;
+       border: 1px solid ButtonShadow;
+       cursor: default;
+       float: left;
        height: 18px;
        overflow: hidden;
-       text-align: center;
-       border: 1px solid ButtonShadow;
        margin: 3px 1px 5px 1px;
-       float: left;
+       padding: 0 2px 4px 0;
+       text-align: center;
+       width: 24px;
 }
 .htmlarea .toolbar .buttonDisabled {
        filter: gray() alpha(opacity=25);
        width: 1px;
 }
 .htmlarea .toolbar .space {
-       background-color:transparent;
-       height:22px;
-       border-style:none;
-       margin:0;
-       padding:0 1px;
-       float:left;
+       background-color: transparent;
+       border-style: none;
+       float: left;
+       height: 22px;
+       margin: 0;
+       padding: 0 1px;
+       width: 2px;
+}
+.htmlarea .toolbar .space-clear-left {
+       clear: left;
+       font-size: 0;
+       height: 0;
+       line-height: 0;
+       overflow: hidden;
 }
 .htmlarea .toolbar .select {
        color: WindowText;
        height: 17px;
 }
-.htmlarea .toolbar .x-form-item label.x-form-item-label {
-       padding-right: 0;
-}
 .htmlarea .toolbar .x-form-field-wrap .x-form-trigger {
        right: 0;
 }