[TASK] Migrate to ExtJS 4: Migrate Backend Base Components
authorStanislas Rolland <typo3@sjbr.ca>
Wed, 7 Dec 2011 18:07:06 +0000 (13:07 -0500)
committerSteffen Ritter <info@rs-websystems.de>
Tue, 13 Dec 2011 07:51:19 +0000 (08:51 +0100)
1. Migrate BE viewport.js
2. Migrate BE module menu.
3. Migrate BE top bar components
4. Migrate context help.
5. Migrate notifications.

Change-Id: I324f4679da0d02e52b93cf265e0befe5762e4013
Resolves: #32189
Releases: 4.7
Reviewed-on: http://review.typo3.org/7096
Tested-by: Stefan Neufeind
Reviewed-by: Steffen Ritter
Tested-by: Steffen Ritter
21 files changed:
t3lib/js/extjs/ExtDirect.StateProvider.js
t3lib/js/extjs/contexthelp.js
t3lib/js/extjs/notifications.js
t3lib/js/extjs/tceforms.js
typo3/backend.php
typo3/classes/class.livesearch.php
typo3/js/extjs/debugPanel.js
typo3/js/extjs/iframepanel.js
typo3/js/extjs/modulepanel.js
typo3/js/extjs/viewport.js
typo3/js/extjs/viewportConfiguration.js
typo3/js/flashupload.js
typo3/js/livesearch.js
typo3/js/loginrefresh.js
typo3/js/modulemenu.js
typo3/js/pagetreefiltermenu.js
typo3/sysext/t3skin/stylesheets/structure/element_docheader.css
typo3/sysext/t3skin/stylesheets/structure/toolbar_livesearch.css [new file with mode: 0644]
typo3/sysext/t3skin/stylesheets/structure/topbar.css
typo3/sysext/t3skin/stylesheets/visual/element_docheader.css
typo3/sysext/t3skin/stylesheets/visual/toolbar_livesearch.css

index fb88288..25fdffb 100644 (file)
@@ -23,9 +23,6 @@
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3.state');
-
 /**
  * Creates new ExtDirectProvider
  * @constructor
@@ -33,72 +30,72 @@ Ext.ns('TYPO3.state');
  * @author Jozef Sakalos
  * @author Steffen Kamper
  */
+Ext.define('TYPO3.state.ExtDirectProvider', {
+       extend: 'Ext.state.Provider',
+
+       constructor: function(config) {
+               this.addEvents(
+                       /**
+                        * @event readsuccess
+                        * Fires after state has been successfully received from server and restored
+                        * @param {HttpProvider} this
+                        */
+                               'readsuccess',
+                       /**
+                        * @event readfailure
+                        * Fires in the case of an error when attempting to read state from server
+                        * @param {HttpProvider} this
+                        */
+                               'readfailure',
+                       /**
+                        * @event savesuccess
+                        * Fires after the state has been successfully saved to server
+                        * @param {HttpProvider} this
+                        */
+                               'savesuccess',
+                       /**
+                        * @event savefailure
+                        * Fires in the case of an error when attempting to save state to the server
+                        * @param {HttpProvider} this
+                        */
+                               'savefailure'
+               );
+
+                       // call parent
+               this.callParent(arguments);
+
+               Ext.apply(this, config, {
+                       // defaults
+                       delay: 750, // buffer changes for 750 ms
+                       dirty: false,
+                       started: false,
+                       autoStart: true,
+                       autoRead: true,
+                       key: 'States.General',
+                       logFailure: false,
+                       logSuccess: false,
+                       queue: [],
+                       saveBaseParams: {},
+                       readBaseParams: {},
+                       paramNames:{
+                               key: 'key',
+                               name: 'name',
+                               value: 'value',
+                               data: 'data'
+                       }
+               });
 
-TYPO3.state.ExtDirectProvider = function(config) {
-
-       this.addEvents(
-               /**
-                * @event readsuccess
-                * Fires after state has been successfully received from server and restored
-                * @param {HttpProvider} this
-                */
-                       'readsuccess',
-               /**
-                * @event readfailure
-                * Fires in the case of an error when attempting to read state from server
-                * @param {HttpProvider} this
-                */
-                       'readfailure',
-               /**
-                * @event savesuccess
-                * Fires after the state has been successfully saved to server
-                * @param {HttpProvider} this
-                */
-                       'savesuccess',
-               /**
-                * @event savefailure
-                * Fires in the case of an error when attempting to save state to the server
-                * @param {HttpProvider} this
-                */
-                       'savefailure'
-                       );
-
-               // call parent
-       TYPO3.state.ExtDirectProvider.superclass.constructor.call(this);
-
-       Ext.apply(this, config, {
-               // defaults
-               delay: 750, // buffer changes for 750 ms
-               dirty: false,
-               started: false,
-               autoStart: true,
-               autoRead: true,
-               key: 'States.General',
-               logFailure: false,
-               logSuccess: false,
-               queue: [],
-               saveBaseParams: {},
-               readBaseParams: {},
-               paramNames:{
-                       key: 'key',
-                       name: 'name',
-                       value: 'value',
-                       data: 'data'
+               if (this.autoRead) {
+                       this.readState();
                }
-       });
-
-       if (this.autoRead) {
-               this.readState();
-       }
-
-       this.dt = new Ext.util.DelayedTask(this.submitState, this);
-       if (this.autoStart) {
-               this.start();
-       }
-};
 
+               this.dt = Ext.create('Ext.util.DelayedTask', this.submitState, this);
+               if (this.autoStart) {
+                       this.start();
+               }
 
-Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
+               return this;
+       },
 
                // localizable texts
        saveSuccessText: 'Save Success',
@@ -107,8 +104,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
        readFailureText: 'Read Failure',
        dataErrorText: 'Data Error',
 
-
-
        /**
         * Initializes state from the passed state object or array.
         * Use this with loading page using initial state in TYPO3.settings
@@ -141,7 +136,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                this.queueChange(name, value);
        },
 
-
        /**
         * Starts submitting state changes to server
         */
@@ -150,7 +144,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                this.started = true;
        },
 
-
        /**
         * Stops submitting state changes
         */
@@ -159,7 +152,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                this.started = false;
        },
 
-
        /**
         * private, queues the state change if state has changed
         */
@@ -197,7 +189,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                return changed;
        },
 
-
        /**
         * private, submits state to server by asynchronous Ajax request
         */
@@ -234,7 +225,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
           }, this);
        },
 
-
        /**
         * Clears the state variable
         * @param {String} name Name of the variable to clear
@@ -243,7 +233,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                this.set(name, undefined);
        },
 
-
        /**
         * private, save success callback
         */
@@ -293,7 +282,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                }
        },
 
-
        /**
         * private, save failure callback
         */
@@ -305,7 +293,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                this.fireEvent('savefailure', this);
        },
 
-
        /**
         * private, read state callback
         */
@@ -317,7 +304,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
 
        },
 
-
        /**
         * private, read success callback
         */
@@ -341,7 +327,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
                }
        },
 
-
        /**
         * Reads saved state from server by sending asynchronous Ajax request and processing the response
         */
@@ -364,7 +349,6 @@ Ext.extend(TYPO3.state.ExtDirectProvider, Ext.state.Provider, {
           }, this);
        },
 
-
        /**
         * private, logs errors or successes
         */
index 6ff8c8f..8b352ca 100644 (file)
@@ -38,7 +38,7 @@ TYPO3.ContextHelp = function() {
         * Cache for CSH
         * @type {Ext.util.MixedCollection}
         */
-       var cshHelp = new Ext.util.MixedCollection(true),
+       var cshHelp = Ext.create('Ext.util.MixedCollection', true),
        tip;
 
        /**
@@ -53,7 +53,7 @@ TYPO3.ContextHelp = function() {
                var table = link.getAttribute('data-table');
                var field = link.getAttribute('data-field');
                var key = table + '.' + field;
-               var response = cshHelp.key(key);
+               var response = cshHelp.getByKey(key);
                tip.target = tip.triggerElement;
                if (response) {
                        updateTip(response);
@@ -97,14 +97,14 @@ TYPO3.ContextHelp = function() {
         * @param {Object} response
         */
        function updateTip(response) {
-               tip.body.dom.innerHTML = response.description;
+               tip.getComponent('description').update(response.description);
                tip.cshLink = response.id;
                tip.moreInfo = response.moreInfo;
                if (tip.moreInfo) {
-                       tip.addClass('tipIsLinked');
+                       tip.addCls('tipIsLinked');
                }
                tip.setTitle(response.title);
-               tip.doAutoWidth();
+               tip.doLayout();
        }
 
 
@@ -113,11 +113,12 @@ TYPO3.ContextHelp = function() {
                 * Constructor
                 */
                init: function() {
-                       tip = new Ext.ToolTip({
-                               title: 'CSH', // needs a title for init because of the markup
-                               html: '',
+                       tip = Ext.create('Ext.tip.ToolTip', {
                                        // The tooltip will appear above the label, if viewport allows
                                anchor: 'bottom',
+                                       // When anchor position is 'top' or 'bottom', the anchor is pushed slightly to the left in order to align with the help icon, if any
+                               anchorOffset: -10,
+                               layout: 'anchor',
                                minWidth: 160,
                                maxWidth: 240,
                                target: Ext.getBody(),
@@ -131,6 +132,15 @@ TYPO3.ContextHelp = function() {
                                hideDelay: 300, // hide after 0.3 seconds
                                closable: true,
                                isMouseOver: false,
+                               items: [
+                                       {
+                                               xtype: 'component',
+                                               itemId: 'description',
+                                               autoEl: {
+                                                       tag: 'span'
+                                               }
+                                       }
+                               ],
                                listeners: {
                                        beforeshow: showToolTipHelp,
                                        render: function(tip) {
@@ -149,7 +159,7 @@ TYPO3.ContextHelp = function() {
                                                                }
                                                        }
                                                });
-                                               tip.el.on({
+                                               tip.getEl().on({
                                                        'mouseover': {
                                                                fn: function() {
                                                                        if (tip.moreInfo) {
@@ -161,7 +171,7 @@ TYPO3.ContextHelp = function() {
                                                                fn: function() {
                                                                        if (tip.moreInfo) {
                                                                                tip.isMouseOver = false;
-                                                                               tip.hide.defer(tip.hideDelay, tip, []);
+                                                                               Ext.Function.defer(tip.hide, tip.hideDelay, tip, []);
                                                                        }
                                                                }
                                                        }
@@ -169,7 +179,7 @@ TYPO3.ContextHelp = function() {
                                        },
                                        hide: function(tip) {
                                                tip.setTitle('');
-                                               tip.body.dom.innerHTML = '';
+                                               tip.getComponent('description').update('');
                                        },
                                        beforehide: function(tip) {
                                                return !tip.isMouseOver;
@@ -194,22 +204,15 @@ TYPO3.ContextHelp = function() {
                        /**
                         * Adds a sequence to Ext.TooltTip::showAt so as to increase vertical offset when anchor position is 'botton'
                         * This positions the tip box closer to the target element when the anchor is on the bottom side of the box
-                        * When anchor position is 'top' or 'bottom', the anchor is pushed slightly to the left in order to align with the help icon, if any
                         *
                         */
-                       Ext.ToolTip.prototype.showAt = Ext.ToolTip.prototype.showAt.createSequence(
+                       Ext.tip.ToolTip.prototype.showAt = Ext.Function.createSequence(
+                               Ext.tip.ToolTip.prototype.showAt,
                                function() {
-                                       var ap = this.getAnchorPosition().charAt(0);
                                        if (this.anchorToTarget && !this.trackMouse) {
-                                               switch (ap) {
-                                                       case 'b':
-                                                               var xy = this.getPosition();
-                                                               this.setPagePosition(xy[0]-10, xy[1]+5);
-                                                               break;
-                                                       case 't':
-                                                               var xy = this.getPosition();
-                                                               this.setPagePosition(xy[0]-10, xy[1]);
-                                                               break;
+                                               if (this.getAnchorPosition().charAt(0) == 'b') {
+                                                       var xy = this.getPosition();
+                                                       this.setPagePosition(xy[0], xy[1]+5);
                                                }
                                        }
                                }
index a3f9b03..154e3fa 100644 (file)
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3', 'TYPO3.Components');
-
 /**
  * TYPO3window - General TYPO3 window component
  */
-TYPO3.Components.Window = Ext.extend(Ext.Window, {
+Ext.define('TYPO3.Components.Window', {
+       extend: 'Ext.window.Window',
+       alias: ['widget.TYPO3window'],
+
        width: 450,
-       autoHeight: true,
        closable: true,
        resizable: false,
        plain: true,
@@ -40,16 +39,8 @@ TYPO3.Components.Window = Ext.extend(Ext.Window, {
        modal: true,
        draggable: true,
        closeAction: 'hide',
-       cls: 't3-window',
-
-       constructor: function(config) {
-               config = config || {};
-               Ext.apply(this, config);
-               TYPO3.Components.Window.superclass.constructor.call(this, config);
-       }
+       cls: 't3-window'
 });
-Ext.reg('TYPO3window', TYPO3.Components.Window);
-
 
 /**
  * Helper class for managing windows.
@@ -66,7 +57,7 @@ Ext.reg('TYPO3window', TYPO3.Components.Window);
  */
 TYPO3.Windows = function() {
        /** @private */
-       var windowCollection = new Ext.util.MixedCollection(true);
+       var windowCollection = Ext.create('Ext.util.MixedCollection', true);
 
        return {
                /** @public */
@@ -86,7 +77,7 @@ TYPO3.Windows = function() {
                        if (window) {
                                return window;
                        } else {
-                               window = new TYPO3.Components.Window(configuration);
+                               window = Ext.create('TYPO3.Components.Window', configuration);
                                windowCollection.add(window);
                                return window;
                        }
@@ -126,7 +117,7 @@ TYPO3.Windows = function() {
                 * @return {Object} window or false if not found
                 */
                getById: function(id) {
-                       return windowCollection.key(id);
+                       return windowCollection.getByKey(id);
                },
 
                /**
@@ -144,7 +135,7 @@ TYPO3.Windows = function() {
                 * @return {Int} count
                 */
                getCount: function() {
-                       return windowCollection.length;
+                       return windowCollection.getCount();
                },
 
                /**
@@ -154,7 +145,7 @@ TYPO3.Windows = function() {
                 * @param {Object} scope
                 * @return void
                 */
-               each : function(fn, scope) {
+               each: function(fn, scope) {
                        windowCollection.each(fn, scope);
                },
 
@@ -231,7 +222,7 @@ TYPO3.Dialog = function() {
                                        informationDialogConfiguration,
                                        configuration
                                        );
-                       Ext.Msg.show(configuration);
+                       Ext.MessageBox.show(configuration);
                },
 
                QuestionDialog: function(configuration) {
@@ -240,7 +231,7 @@ TYPO3.Dialog = function() {
                                        questionDialogConfiguration,
                                        configuration
                                        );
-                       Ext.Msg.show(configuration);
+                       Ext.MessageBox.show(configuration);
                },
 
                WarningDialog: function(configuration) {
@@ -249,7 +240,7 @@ TYPO3.Dialog = function() {
                                        warningDialogConfiguration,
                                        configuration
                                        );
-                       Ext.Msg.show(configuration);
+                       Ext.MessageBox.show(configuration);
                },
 
                ErrorDialog: function(configuration) {
@@ -258,7 +249,7 @@ TYPO3.Dialog = function() {
                                        errorDialogConfiguration,
                                        configuration
                                        );
-                       Ext.Msg.show(configuration);
+                       Ext.MessageBox.show(configuration);
                }
        }
 }();
index 5341134..74e5c90 100644 (file)
@@ -29,7 +29,7 @@ Ext.ns('TYPO3');
 TYPO3.TCEFORMS = {
 
        init: function() {
-               Ext.QuickTips.init();
+               Ext.tip.QuickTipManager.init();
 
                this.convertDateFieldsToDatePicker();
                this.convertTextareasResizable();
@@ -49,15 +49,15 @@ TYPO3.TCEFORMS = {
                        maxDate = Ext.isArray(upperMatch) ? new Date(upperMatch[1] * 1000) : null;
 
                        if (index === 0) {
-                               menu = new Ext.menu.DateMenu({
+                               menu = Ext.create('Ext.menu.DatePicker', {
                                        id: 'p' + element.dom.id,
                                        format: format[index],
-                                       value: Date.parseDate(element.dom.value, format[index]),
+                                       value: Ext.Date.parse(element.dom.value, format[index]),
                                        minDate: minDate,
                                        maxDate: maxDate,
                                        handler: function(picker, date){
                                                var relElement = Ext.getDom(picker.ownerCt.id.substring(1));
-                                               relElement.value = date.format(format[index]);
+                                               relElement.value = Ext.Date.format(date, format[index]);
                                                if (Ext.isFunction(relElement.onchange)) {
                                                        relElement.onchange.call(relElement);
                                                }
@@ -66,28 +66,28 @@ TYPO3.TCEFORMS = {
                                                beforeshow: function(obj) {
                                                        var relElement = Ext.getDom(obj.picker.ownerCt.id.substring(1));
                                                        if (relElement.value) {
-                                                               obj.picker.setValue(Date.parseDate(relElement.value, format[index]));
+                                                               obj.picker.setValue(Ext.Date.parse(relElement.value, format[index]));
                                                        }
                                                }
                                        }
                                });
                        } else {
-                               menu = new Ext.ux.menu.DateTimeMenu({
+                               menu = Ext.create('Ext.ux.menu.DateTimeMenu', {
                                        id: 'p' + element.dom.id,
                                        format: format[index],
-                                       value: Date.parseDate(element.dom.value, format[index]),
+                                       value: Ext.Date.parse(element.dom.value, format[index]),
                                        minDate: minDate,
                                        maxDate: maxDate,
                                        listeners: {
-                                               beforeshow: function(obj) {
+                                               afterlayout: function(obj) {
                                                        var relElement = Ext.getDom(obj.picker.ownerCt.id.substring(1));
                                                        if (relElement.value) {
-                                                               obj.picker.setValue(Date.parseDate(relElement.value, format[index]));
+                                                               obj.picker.setValue(Ext.Date.parse(relElement.value, format[index]));
                                                        }
                                                },
                                                select: function(picker) {
                                                        var relElement = Ext.getDom(picker.ownerCt.id.substring(1));
-                                                       relElement.value = picker.getValue().format(format[index]);
+                                                       relElement.value = Ext.Date.format(picker.getValue(), format[index]);
                                                        if (Ext.isFunction(relElement.onchange)) {
                                                                relElement.onchange.call(relElement);
                                                        }
@@ -95,9 +95,8 @@ TYPO3.TCEFORMS = {
                                        }
                                });
                        }
-
                        datepicker.on('click', function(){
-                               menu.show(datepicker);
+                               menu.showBy(datepicker);
                        });
                });
        },
@@ -106,16 +105,18 @@ TYPO3.TCEFORMS = {
                var textAreas = Ext.select("textarea[id^=tceforms-textarea-]");
                textAreas.each(function(element) {
                        if (TYPO3.settings.textareaFlexible) {
-                               var elasticTextarea = new Ext.ux.elasticTextArea().applyTo(element.dom.id, {
+                               var elasticTextarea = Ext.create('Ext.ux.elasticTextArea').renderTo(element.dom.id, {
                                        minHeight: 50,
                                        maxHeight: TYPO3.settings.textareaMaxHeight
                                });
                        }
                        if (TYPO3.settings.textareaResize) {
-                               element.addClass('resizable');
-                               var dwrapped = new Ext.Resizable(element.dom.id, {
+                               element.addCls('resizable');
+                               var dwrapped = Ext.create('Ext.resizer.Resizer', {
+                                       target: element.dom.id,
                                        minWidth:  300,
                                        minHeight: 50,
+                                       width: element.getWidth(),
                                        dynamic:   true
                                });
                        }
index 213e2b0..9c48f81 100644 (file)
@@ -135,7 +135,7 @@ class TYPO3backend {
                        'iframepanel'           => 'js/extjs/iframepanel.js',
                        'modulepanel'           => 'js/extjs/modulepanel.js',
                        'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
-                       'util'                                  => '../t3lib/js/extjs/util.js',
+                       'util'                  => '../t3lib/js/extjs/util.js',
                );
 
                if ($this->debug) {
@@ -242,7 +242,7 @@ class TYPO3backend {
                $states = $GLOBALS['BE_USER']->uc['BackendComponents']['States'];
                        //save states in BE_USER->uc
                $extOnReadyCode = '
-                       Ext.state.Manager.setProvider(new TYPO3.state.ExtDirectProvider({
+                       Ext.state.Manager.setProvider(Ext.create("TYPO3.state.ExtDirectProvider", {
                                key: "BackendComponents.States",
                                autoRead: false
                        }));
@@ -251,7 +251,7 @@ class TYPO3backend {
                        $extOnReadyCode .= 'Ext.state.Manager.getProvider().initState(' . json_encode($states) . ');';
                }
                $extOnReadyCode .= '
-                       TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
+                       TYPO3.Backend = Ext.create("TYPO3.Viewport", TYPO3.Viewport.configuration);
                        if (typeof console === "undefined") {
                                console = TYPO3.Backend.DebugConsole;
                        }
index 0482529..03fa88d 100644 (file)
@@ -80,10 +80,9 @@ class LiveSearch implements backend_toolbarItem {
         */
        public function render() {
                $this->addJavascriptToBackend();
-               return '<div class="live-search-wrapper">
-                                       <span title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') .'" class="t3-icon t3-icon-apps t3-icon-apps-toolbar t3-icon-toolbar-menu-search">&nbsp;</span>
-                                       <input id="live-search-box" />
-                               </div>';
+               return '<div id="live-search-box" class="live-search-wrapper live-search-results">
+                               <span title="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_common.xml:search') .'" class="t3-icon t3-icon-apps t3-icon-apps-toolbar t3-icon-toolbar-menu-search">&nbsp;</span>
+                       </div>';
        }
 
        /**
index 29ae767..b967177 100644 (file)
@@ -23,9 +23,6 @@
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3');
-
 /**
  * Debug panel based upon the widget tab panel
  *
@@ -44,13 +41,16 @@ Ext.ns('TYPO3');
  *
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
+Ext.define('TYPO3.DebugPanel', {
+       extend: 'Ext.tab.Panel',
+       alias: ['widget.typo3DebugPanel'],
+
        /**
         * Tab Groups
         *
         * @var Ext.util.MixedCollection
         */
-       tabGroups: new Ext.util.MixedCollection(),
+       tabGroups: Ext.create('Ext.util.MixedCollection'),
 
        /**
         * Indicator if the debug panel is wrapped inside a debug panel
@@ -69,14 +69,16 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
        initComponent: function(config) {
                config = config || {};
                Ext.apply(this, config, {
-                               // activate general tab navigation with mouse wheel support
-                       enableTabScroll: true,
+                               // Activate general tab navigation with mouse wheel support
+                       tabBar: {
+                               autoScroll: true
+                       },
                        defaults: {
                                autoScroll: true
                        },
 
                                // add the context menu actions
-                       plugins: new Ext.ux.TabCloseMenu({
+                       plugins: Ext.create('Ext.ux.TabCloseMenu', {
                                closeTabText: TYPO3.LLL.core.tabs_close,
                                closeOtherTabsText: TYPO3.LLL.core.tabs_closeOther,
                                closeAllTabsText: TYPO3.LLL.core.tabs_closeAll,
@@ -90,7 +92,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                                                        var tab = this.plugins.active;
                                                        var group = '', content = '';
 
-                                                       if (tab.ownerCt.ownerCt instanceof Ext.TabPanel) {
+                                                       if (tab.ownerCt.ownerCt instanceof Ext.tab.Panel) {
                                                                group = tab.ownerCt.title;
                                                                content = tab.body.dom.innerHTML;
                                                        } else {
@@ -112,7 +114,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                });
 
 
-               TYPO3.DebugPanel.superclass.initComponent.call(this);
+               this.callParent([config]);
        },
 
        /**
@@ -122,14 +124,14 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         * @return void
         */
        onRender: function() {
-               this.arrow = Ext.DomHelper.append(
+               this.arrow = Ext.core.DomHelper.append(
                        Ext.getBody(),
                        '<div class="typo3-debugPanel-dragDropArrowDown">&nbsp;</div>',
                        true
                );
                this.arrow.hide();
 
-               TYPO3.DebugPanel.superclass.onRender.apply(this, arguments);
+               this.callParent(arguments);
        },
 
        /**
@@ -138,7 +140,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         * @return void
         */
        onCollapse: function() {
-               TYPO3.DebugPanel.superclass.onCollapse.apply(this, arguments);
+               this.callParent(arguments);
        },
 
        /**
@@ -147,7 +149,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         * @return void
         */
        onExpand: function() {
-               TYPO3.DebugPanel.superclass.onExpand.apply(this, arguments);
+               this.callParent(arguments);
        },
 
        /**
@@ -157,7 +159,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         */
        onDestroy: function() {
                Ext.destroy(this.arrow);
-               TYPO3.DebugPanel.superclass.onDestroy.call(this);
+               this.callParent(arguments);
        },
 
        /**
@@ -177,7 +179,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                if (TYPO3.configuration.debugInWindow) {
                        this.openBrowserWindow(header, tabContent, group);
                } else {
-                       var tabWidget = new Ext.Panel({
+                       var tabWidget = Ext.create('Ext.panel.Panel', {
                                title: header,
                                html: tabContent,
                                border: false,
@@ -213,7 +215,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                var tabGroup = this;
                if (typeof group !== 'undefined' && group !== '' && !this.isTabChildren) {
                        if (this.tabGroups.indexOfKey(group) === -1) {
-                               tabGroup = new TYPO3.DebugPanel({
+                               tabGroup = Ext.create('TYPO3.DebugPanel', {
                                        border: false,
                                        title: group,
                                        autoScroll: true,
@@ -282,7 +284,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         * @return void
         */
        initDragAndDropForTab: function(item) {
-               item.tabDragZone = new Ext.dd.DragZone(this.id + '__' + item.id, {
+               item.tabDragZone = Ext.create('Ext.dd.DragZone', this.id + '__' + item.id, {
                        ddGroup: this.id,
 
                        /**
@@ -292,7 +294,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                         */
                        b4MouseDown : function() {
                                item.show();
-                               Ext.dd.DragZone.superclass.b4MouseDown.apply(this, arguments);
+                               this.callParent(arguments);
                        },
 
                        /**
@@ -331,7 +333,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                        }
                });
 
-               item.tabDropZone = new Ext.dd.DropZone(this.id + '__' + item.id, {
+               item.tabDropZone = Ext.create('Ext.dd.DropZone', this.id + '__' + item.id, {
                        debugPanel: this,
                        ddGroup: this.id,
 
@@ -359,7 +361,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                         * @return void
                         */
                        onNodeEnter : function(target) {
-                               Ext.get(target).addClass('typo3-debugPanel-dragDropOver');
+                               Ext.get(target).addCls('typo3-debugPanel-dragDropOver');
                        },
 
                        /**
@@ -369,7 +371,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                         * @return void
                         */
                        onNodeOut : function(target) {
-                               Ext.get(target).removeClass('typo3-debugPanel-dragDropOver');
+                               Ext.get(target).removeCls('typo3-debugPanel-dragDropOver');
                                this.debugPanel.arrow.hide();
                        },
 
@@ -466,7 +468,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                        'width=600,height=400,menubar=0,toolbar=1,status=0,scrollbars=1,resizable=1'
                );
                if (newWindow.document.body.innerHTML) {
-                       Ext.DomHelper.insertHtml('beforeEnd', newWindow.document.body, '<hr>' + content);
+                       Ext.core.DomHelper.insertHtml('beforeEnd', newWindow.document.body, '<hr>' + content);
                } else {
                        newWindow.document.writeln(
                                '<html><head><title>Debug: ' + title + '(' + group + ')</title></head>'
@@ -586,7 +588,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
        },
 
        /**
-        * Debug attached events of a given element (e.g. an Ext.Panel component)
+        * Debug attached events of a given element (e.g. an Ext.panel.Panel component)
         *
         * Note: This functionality should be used with an activated debug console like firebug!
         *
@@ -608,12 +610,10 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                } else {
                                // debug all events
                        Ext.util.Observable.prototype.fireEvent =
-                               Ext.util.Observable.prototype.fireEvent.createInterceptor(function() {
+                               Ext.Function.createInterceptor('Ext.util.Observable.prototype.fireEvent', function() {
                                        console.log(arguments);
                                        return true;
                                });
                }
        }
 });
-
-Ext.reg('typo3DebugPanel', TYPO3.DebugPanel);
index ccd968a..8614400 100644 (file)
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-
-
 /**
  * iFrame panel
  *
  * @author     Steffen Kamper
  */
+Ext.define('TYPO3.iframePanel', {
+       extend: 'Ext.panel.Panel',
+       alias: ['widget.iframePanel'],
 
-Ext.ns('TYPO3');
-
-TYPO3.iframePanel = Ext.extend(Ext.Panel, {
        name: 'iframe',
        iframe: null,
        src: Ext.isIE && Ext.isSecure ? Ext.SSL_SECURE_URL : 'about:blank',
        maskMessage: ' ',
        doMask: true,
-
-               // component build
+       border: false,
+               // Build the iframePanel component
        initComponent: function() {
-               this.bodyCfg = {
-                       tag: 'iframe',
-                       frameborder: '0',
-                       src: this.src,
-                       name: this.name,
-                       style: 'float:left;' // this is needed to prevent offset of 2.5 pixel, see #15771
-               }
-               Ext.apply(this, {
-
+               this.callParent(arguments);
+                       // Add the iframe element as item
+               this.add({
+                       xtype: 'component',
+                       itemId: 'iframe',
+                       autoEl: {
+                               tag: 'iframe',
+                               name: this.name,
+                               frameborder: '0',
+                               src: this.src
+                       },
+                       listeners: {
+                               afterrender: {
+                                       fn: this.onAfterRender,
+                                       scope: this,
+                                       single: true
+                               }
+                       }
                });
-               TYPO3.iframePanel.superclass.initComponent.apply(this, arguments);
-
-               // apply the addListener patch for 'message:tagging'
-               this.addListener = this.on;
-
        },
-
-       onRender : function() {
-               TYPO3.iframePanel.superclass.onRender.apply(this, arguments);
+       onAfterRender: function() {
                this.maskMessage = ' ';
-               this.iframe = Ext.isIE ? this.body.dom.contentWindow : window.frames[this.name];
-               this.body.dom[Ext.isIE ? 'onreadystatechange' : 'onload'] = this.loadHandler.createDelegate(this);
+               this.iframeEl = this.getComponent('iframe').getEl();
+               this.iframe = Ext.isIE ? this.iframeEl.dom.contentWindow : window.frames[this.name];
+               this.iframeEl.dom[Ext.isIE ? 'onreadystatechange' : 'onload'] = Ext.Function.bind(this.loadHandler, this);
        },
 
        loadHandler: function() {
-               this.src = this.body.dom.src;
+               this.src = this.iframeEl.dom.src;
                this.removeMask();
        },
 
@@ -75,43 +76,46 @@ TYPO3.iframePanel = Ext.extend(Ext.Panel, {
                return this.iframe;
        },
        getUrl: function() {
-               return this.body.dom.src;
+               return this.iframeEl.dom.src;
        },
 
        setUrl: function(source) {
                this.setMask();
-               this.body.dom.src = source;
+               this.iframeEl.dom.src = source;
        },
 
        resetUrl: function() {
                this.setMask();
-               this.body.dom.src = this.src;
+               this.iframeEl.dom.src = this.src;
        },
 
        getIdFromUrl: function() {
-               var url = Ext.urlDecode(this.getUrl().split('?')[1]);
-               return url.id;
+               var queryString = this.getUrl().split('?')[1];
+               if (queryString) {
+                       var url = Ext.urlDecode(queryString);
+               }
+               return url ? url.id : null;
        },
 
        refresh: function() {
                if (!this.isVisible()) {
-            return;
-        }
-        this.setMask();
-               this.body.dom.src = this.body.dom.src;
+                   return;
+               }
+               this.setMask();
+               this.iframeEl.dom.src = this.iframeEl.dom.src;
        },
 
        /** @private */
        setMask: function() {
                if (this.doMask) {
-                       this.el.mask(this.maskMessage, 'x-mask-loading-message');
-                       this.el.addClass('t3-mask-loading');
-                               // add an onClick handler to remove the mask while clicking on the loading message
+                       this.getEl().mask(this.maskMessage, 'x-mask-loading-message');
+                       this.getEl().addCls('t3-mask-loading');
+                               // Add an onClick handler to remove the mask while clicking on the loading message
                                // useful if user cancels loading and wants to access the content again
-                       this.el.child('.x-mask-loading-message').on(
+                       this.getEl().child('.x-mask-loading-message').on(
                                'click',
                                function() {
-                                       this.el.unmask();
+                                       this.getEl().unmask();
                                },
                                this
                        );
@@ -120,8 +124,7 @@ TYPO3.iframePanel = Ext.extend(Ext.Panel, {
 
        removeMask: function() {
                if (this.doMask) {
-                       this.el.unmask();
+                       this.getEl().unmask();
                }
        }
 });
-Ext.reg('iframePanel', TYPO3.iframePanel);
index 6e5bf55..129b7e1 100644 (file)
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
+Ext.define('TYPO3.modulePanel', {
+       extend: 'Ext.panel.Panel',
+       alias: ['widget.modulePanel'],
 
-TYPO3.modulePanel = Ext.extend(Ext.Panel, {
        name: 'modulePanel',
        maskMessage: ' ',
        doMask: true,
@@ -39,7 +41,6 @@ TYPO3.modulePanel = Ext.extend(Ext.Panel, {
                                cls: 't3skin-typo3-module-panel-toolbar'
                        }
                });
-               TYPO3.modulePanel.superclass.initComponent.apply(this, arguments);
+               this.callParent(arguments);
        }
-});
-Ext.reg('modulePanel', TYPO3.modulePanel);
\ No newline at end of file
+});
\ No newline at end of file
index f4b1331..9d817fb 100644 (file)
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3');
-
-       // override splitregion to fit the splitbars in our design
-Ext.override(Ext.layout.BorderLayout.SplitRegion, {
-       render : function(ct, p) {
-               Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
-
-               var ps = this.position;
-
-               this.splitEl = ct.createChild({
-                       cls: "x-layout-split x-layout-split-" + ps, html: " ",
-                       id: this.panel.id + '-xsplit'
-               });
-
-               if (this.enableChildSplit) {
-                       this.splitChildEl = this.splitEl.createChild({
-                               cls: 'x-layout-mini-wrapper'
-                       });
-
-               }
-               if (this.collapseMode == 'mini') {
-                       this.miniSplitEl = this.splitEl.createChild({
-                               cls: "x-layout-mini x-layout-mini-" + ps, html: " "
-                       });
-                       this.miniSplitEl.addClassOnOver('x-layout-mini-over');
-                       this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
-               }
-
-               var s = this.splitSettings[ps];
-
-               if (this.enableChildSplit) {
-                       this.split = new Ext.SplitBar(this.splitChildEl.dom, p.el, s.orientation);
-               } else {
-                       this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
-               }
-               this.split.tickSize = this.tickSize;
-               this.split.placement = s.placement;
-               this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
-               this.split.minSize = this.minSize || this[s.minProp];
-               this.split.on("beforeapply", this.onSplitMove, this);
-               this.split.useShim = this.useShim === true;
-               this.maxSize = this.maxSize || this[s.maxProp];
-
-               if (p.hidden) {
-                       this.splitEl.hide();
-               }
-
-               if (this.useSplitTips) {
-                       this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
-               }
-               if (this.collapsible) {
-                       this.splitEl.on("dblclick", this.onCollapseClick, this);
-               }
-       }
-});
 /**
  * Extends the viewport with some functionality for TYPO3.
  *
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Viewport = Ext.extend(Ext.Viewport, {
+Ext.define('TYPO3.Viewport', {
+       extend: 'Ext.container.Viewport',
+       alias: ['widget.typo3Viewport'],
+
        /**
         * Contains the navigation widgets in a simple array and identified by an unique idea
         *
@@ -156,15 +103,14 @@ TYPO3.Viewport = Ext.extend(Ext.Viewport, {
         * @return void
         */
        initComponent: function() {
-               // adjust the module menu and the height of the topbar
-               this.initialConfig.items[0].height = TYPO3.configuration.topBarHeight;
-
+                       // Adjust the height of the topbar and the width of the module menu
+               var topbar = this.initialConfig.items[0];
+               topbar.height = TYPO3.configuration.topBarHeight;
                var moduleMenu = this.initialConfig.items[1];
                moduleMenu.width = TYPO3.configuration.moduleMenuWidth;
-
-               // call parent constructor
-               TYPO3.Viewport.superclass.initComponent.apply(this, arguments);
-
+                       // Call parent
+               this.callParent(arguments);
+                       // Set references to components
                this.ContentContainer = Ext.getCmp('typo3-contentContainer');
                this.NavigationContainer = Ext.getCmp('typo3-navigationContainer');
                this.NavigationDummy = Ext.getCmp('typo3-navigationDummy');
@@ -172,8 +118,5 @@ TYPO3.Viewport = Ext.extend(Ext.Viewport, {
                this.Topbar = Ext.getCmp('typo3-topbar');
                this.ModuleMenuContainer = Ext.getCmp('typo3-module-menu');
                this.DebugConsole = Ext.getCmp('typo3-debug-console');
-
        }
 });
-
-Ext.reg('typo3Viewport', TYPO3.Viewport);
index 7bda328..f1b5b4c 100644 (file)
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3');
-
 /**
  * The backend viewport configuration
  *
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
+Ext.ns('TYPO3.Viewport');
 TYPO3.Viewport.configuration = {
        layout: 'border',
        id: 'typo3-viewport',
@@ -41,7 +39,7 @@ TYPO3.Viewport.configuration = {
                        layout: 'absolute',
                        region: 'north',
                        id: 'typo3-topbar',
-                       height: 42,
+                       height: TYPO3.configuration.topBarHeight,
                        contentEl: 'typo3-top-container',
                        border: false
                },
@@ -49,16 +47,18 @@ TYPO3.Viewport.configuration = {
                        layout: 'fit',
                        region: 'west',
                        id: 'typo3-module-menu',
-                       collapsible: false,
-                       collapseMode: null,
+                       animCollapse: false,
+                       autoScroll: true,
+                       border: false,
+                       collapsible: true,
                        floatable: true,
                        hideCollapseTool: true,
+                       name: 'modulePanel',
                        split: true,
                        useSplitTips: true,
                        splitTip: top.TYPO3.LLL.viewPort.tooltipModuleMenuSplit,
                        enableChildSplit: true,
-                       border: false,
-                       autoScroll: true
+                       width: TYPO3.configuration.moduleMenuWidth
                },
                {
                        region: 'center',
@@ -69,6 +69,7 @@ TYPO3.Viewport.configuration = {
                                        region: 'west',
                                        layout: 'fit',
                                        id: 'typo3-navigationContainer',
+                                       autoScroll: true,
                                        width: 300,
                                        minWidth: 20,
                                        floatable: true,
@@ -83,12 +84,15 @@ TYPO3.Viewport.configuration = {
                                        hidden: true,
                                        border: false,
                                        name: 'navigation',
-                                       autoScroll: true,
                                        items: [
                                                {
                                                        id: 'typo3-navigationIframe',
                                                        border: false,
                                                        hidden: true,
+                                                       layout: {
+                                                               type: 'vbox',
+                                                               align: 'stretch'
+                                                       },
                                                        xtype: 'iframePanel',
                                                        name: 'navigation'
                                                }
@@ -105,16 +109,16 @@ TYPO3.Viewport.configuration = {
                                                        border: false,
                                                        hidden: true,
                                                        floatable: true,
-                                                       xtime: 'iframePanel',
-                                                       width: 5
+                                                       xtype: 'iframePanel',
+                                                       width: 0
                                                },
                                                {
                                                        id: 'typo3-contentContainer',
-                                                       region: 'center',
-                                                       anchor: '100% 100%',
                                                        border: false,
-                                                       xtype: 'iframePanel',
-                                                       name: 'content'
+                                                       layout: 'fit',
+                                                       name: 'content',
+                                                       region: 'center',
+                                                       xtype: 'iframePanel'
                                                }
                                        ]
                                },
index f4f4f8f..7d06ae9 100644 (file)
@@ -230,7 +230,7 @@ Ext.onReady(function() {
                        // add a placeholder div next to the button itself, so it can be detected and replaced by the flash plugin
                        if (!Ext.fly(swfConfig.button_placeholder_id)) {
                                var button = Ext.DomQuery.selectNode('#t3-file-upload-window-button-selectfiles button');
-                               Ext.DomHelper.insertBefore(button, '<div id="' + swfConfig.button_placeholder_id + '"></div>');
+                               Ext.core.DomHelper.insertBefore(button, '<div id="' + swfConfig.button_placeholder_id + '"></div>');
                                // set the width of the swf-button in background according to the user-visible button
                                swfConfig.button_width = button.clientWidth;
                        }
index bd27540..a1b0fae 100644 (file)
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.namespace('TYPO3');
-
-TYPO3.BackendLiveSearch = Ext.extend(Ext.form.ComboBox, {
-       autoSelect: false,
-       ctCls: 'live-search-results',
+Ext.define('TYPO3.BackendLiveSearch.Model', {
+       extend: 'Ext.data.Model',
+       fields: [{
+               name: 'id',
+               type: 'string'
+       },{
+               name: 'type',
+               type: 'string'
+       },{
+               name: 'recordTitle',
+               type: 'string'
+       },{
+               name: 'iconHTML',
+               type: 'string'
+       },{
+               name: 'title',
+               type: 'string'
+       },{
+               name: 'editLink',
+               type: 'string'
+       },{
+               name: 'pageJump',
+               type: 'string'
+       }]
+});
+/**
+ * Extend Boundlist layout (ExtJS 4.0.7)
+ * Make space for live search toolbar
+ * Should be reviewed on ExtJS upgrade
+ */
+Ext.define('TYPO3.BackendLiveSearch.BoundList.Layout', {
+       extend: 'Ext.layout.component.BoundList',
+       alias: 'layout.livesearchboundlist',
+       setTargetSize: function (width, height) {
+               var me = this,
+                       owner = me.owner,
+                       listHeight = null,
+                       toolbar;
+               me.callParent(arguments);
+                       // Size the listEl
+               if (Ext.isNumber(height)) {
+                       listHeight = height - owner.el.getFrameWidth('tb');
+                               // Make space for live search toolbar
+                       toolbar = owner.liveSearchToolbar;
+                       if (toolbar) {
+                               listHeight -= toolbar.getHeight();
+                       }
+               }
+               me.setElementSize(owner.listEl, null, listHeight);
+       }
+});
+/**
+ * Extend Boundlist (ExtJS 4.0.7)
+ * Add live search toolbar instead of paging toolbar
+ * Should be reviewed on ExtJS upgrade
+ */
+Ext.define('TYPO3.BackendLiveSearch.BoundList', {
+       extend: 'Ext.view.BoundList',
+       /**
+        * Use extended boundlist layout
+        */
+       componentLayout: 'livesearchboundlist',
+       /**
+        * Create live search toolbar when the boundlist is initialized
+        */
+       initComponent: function() {
+               this.liveSearchToolbar = this.createLiveSearchToolbar();
+               this.callParent();
+       },
+       /**
+        * Render the live search toolbar when the boundlist is rendered
+        */
+       onRender: function() {
+               var me = this,
+                       toolbar = me.liveSearchToolbar;
+               me.callParent(arguments);
+               if (toolbar) {
+                       toolbar.render(me.el);
+               }
+       },
+       /**
+        * Create the live search toolbar
+        *
+        * @return      Object{Ext.toolbar.Toolbar}
+        */
+       createLiveSearchToolbar: function () {
+               return Ext.create('Ext.toolbar.Toolbar', {
+                       height: 30,
+                       items: [{
+                               xtype: 'tbfill',
+                               flex: 1
+                       },{
+                               xtype: 'button',
+                               text: TYPO3.LLL.liveSearch.showAllResults,
+                               arrowAlign: 'right',
+                               shadow: false,
+                               icon: '../typo3/sysext/t3skin/icons/module_web_list.gif',
+                               listeners: {
+                                       click: {
+                                               fn: function () {
+                                                               // go to db_list.php and search for given search value
+                                                               // @todo the current selected page ID from the page tree is required, also we need the
+                                                               // values of $GLOBALS['BE_USER']->returnWebmounts() to search only during the allowed pages
+                                                       TYPO3.ModuleMenu.App.showModule('web_list', this.pickerField.getSearchResultsUrl(this.pickerField.getValue()));
+                                                       this.pickerField.collapse();
+                                               },
+                                               scope: this
+                                       }
+                               }
+                       }]
+               });
+       }
+});
+/**
+ * Extend Ext.form.field.ComboBox (ExtJS 4.0.7)
+ * Review createPicker method on ExtJS upgrade
+ */
+Ext.define('TYPO3.BackendLiveSearch.ComboBox', {
+       extend: 'Ext.form.field.ComboBox',
        dataProvider: null,
-       searchResultsPid : 0,
+       searchResultsPid: 0,
+       autoSelect: false,
        displayField: 'title',
-       emptyText: null,
+       emptyText: '',
        enableKeyEvents: true,
        helpTitle: null,
        hideTrigger: true,
-       itemSelector: 'div.search-item-title',
-       listAlign : 'tr-br',
-       listClass: 'live-search-list',
-       listEmptyText: null,
-       listWidth: 315,
-       listHovered: false,
-       loadingText: null,
+       listConfig: {
+               cls: 'live-search-list',
+               itemCls: 'search-item-title',
+               tpl: Ext.create('Ext.XTemplate',
+                       '<table>',
+                               '<tr><th colspan="2" class="live-search-list-title">' + TYPO3.LLL.liveSearch.title + '<th><tr>',
+                               '<tpl for=".">',
+                                       '<tr class="search-item">',
+                                               '<td class="search-item-type">{recordTitle}</td>',
+                                               '<td class="search-item-content">',
+                                                       '<div class="search-item-title">{iconHTML} {title}</div>',
+                                               '</td>',
+                                       '</tr>',
+                               '</tpl>',
+                       '</table>'
+               ),
+               loadingHeight: '200',
+               loadingText: '',
+               overCls: 'live-search-list-over',
+               resizable: false,
+               width: 315,
+               listeners: {
+                               // Keep the focus on the input field so that the blur event is triggered when another iframe is clicked
+                       containermouseout: {
+                               fn: function (list) {
+                                       list.pickerField.focus();
+                               }
+                       }
+               }
+       },
        minChars: 1,
-       resizable: false,
+       pickerAlign: 'tr-br',
        title: null,
+       triggerBaseCls: 'x-form-trigger t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-tceforms-input-clearer',
        width: 205,
-       triggerClass : 'x-form-clear-trigger',
-       triggerConfig: '<span tag="a" class="t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-tceforms-input-clearer">&nbsp;</span>',
-       onTriggerClick: function() {
-               // Empty the form field, give it focus, and collapse the results
-               this.reset(this);
-               this.focus();
-               this.collapse();
-       },
-       tpl: new Ext.XTemplate(
-               '<table border="0" cellspacing="0">',
-                       '<tpl for=".">',
-                               '<tr class="search-item">',
-                                       '<td class="search-item-type" width="105" align="right">{recordTitle}</td>',
-                                       '<td class="search-item-content" width="195">',
-                                               '<div class="search-item-title">{iconHTML} {title}</div>',
-                                       '</td>',
-                               '</tr>',
-                       '</tpl>',
-               '</table>'
-       ),
-
-       dataReader : new Ext.data.JsonReader({
-               idProperty : 'type',
-               root : 'searchItems',
-               fields : [
-                       {name: 'recordTitle'},
-                       {name: 'id'},
-                       {name: 'iconHTML'},
-                       {name: 'title'},
-                       {name: 'editLink'}
-               ]
-       }),
        listeners: {
-               select : {
-                       scope: this,
-                       fn: function (combo, record, index) {
-                               jump(record.data.editLink, 'web_list', 'web');
+               select: {
+                       fn: function (combo, records) {
+                                       // We do not wish to have the value selected in the results list
+                                       // to be displayed in the search field.
+                               combo.setRawValue(combo.lastQuery);
+                               jump(records[0].get('editLink'), 'web_list', 'web');
                        }
                },
-               focus : {
-                       fn: function() {
-                               if (this.getValue() == this.emptyText) {
-                                       this.reset(this);
+                       // If the search field is null, blank or emptyText, show the help on focus.
+                       // Otherwise, show last results
+               focus: {
+                       fn: function (combo) {
+                               if (!combo.getValue() || combo.getValue() == combo.emptyText) {
+                                       combo.initHelp();
+                               } else {
+                                       combo.expand();
                                }
+
+                       }
+               },
+               blur: {
+                       fn: function (combo) {
+                               combo.collapse();
+                               combo.removeHelp();
                        }
                },
-               specialkey : function (field, e) {
-                       if (e.getKey() == e.RETURN || e.getKey() == e.ENTER) {
-                               if (this.dataReader.jsonData.pageJump != '') {
-                                       jump(this.dataReader.jsonData.pageJump, 'web_list', 'web');
+               keyup: {
+                       fn: function (combo, event) {
+                               if (!combo.getValue() || combo.getValue() == combo.emptyText) {
+                                       combo.setHideTrigger(true);
                                } else {
-                                       TYPO3.ModuleMenu.App.showModule('web_list', this.getSearchResultsUrl(this.getValue()));
+                                       combo.setHideTrigger(false);
                                }
                        }
                },
-               keyup : function() {
-                       if ((this.getValue() == this.emptyText) || (this.getValue() == '')) {
-                               this.setHideTrigger(true);
-                       } else {
-                               this.setHideTrigger(false);
+               specialkey: {
+                       fn: function (combo, event) {
+                               if (event.getKey() == event.RETURN || event.getKey() == event.ENTER) {
+                                       var rawData = combo.getStore().getProxy().getReader().rawData;
+                                       if (rawData && rawData.pageJump != '') {
+                                               jump(rawData.pageJump, 'web_list', 'web');
+                                       } else {
+                                               TYPO3.ModuleMenu.App.showModule('web_list', this.getSearchResultsUrl(combo.getValue()));
+                                       }
+                               }
+                       }
+               },
+               beforequery: {
+                       fn: function (queryEvent) {
+                               queryEvent.combo.removeHelp();
                        }
                }
        },
 
        /**
-        * Initializes the component.
+        * Create the store and initialize the component.
         */
        initComponent: function() {
-               this.store = new Ext.data.DirectStore({
-                       directFn: this.dataProvider.find,
-                       reader: this.dataReader
-               });
-               TYPO3.BackendLiveSearch.superclass.initComponent.apply(this, arguments);
-       },
-
-       restrictHeight : function(){
-               this.innerList.dom.style.height = '';
-               var inner = this.innerList.dom;
-               var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight + 30; // @todo Remove hardcoded 30
-               var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
-               var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
-               var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
-               var space = Math.max(ha, hb, this.minHeight || 0)-pad-2;
-               /** BUG FIX **/
-               if (this.shadow === true) { space-=this.list.shadow.offset; }
-
-               h = Math.min(h, space, this.maxHeight);
-
-               /**
-                * @internal The calcated height of "h" in the line before seems not working as expected.
-                *                       If i define a min height, the box shold at least use this height also if only one entry is in there
-                */
-               //h = this.maxHeight;
-
-               this.innerList.setHeight(h);
-               this.list.beginUpdate();
-               this.list.setHeight(h+pad);
-               this.list.alignTo(this.el, this.listAlign);
-               this.list.endUpdate();
+               this.store = Ext.data.StoreManager.lookup(this.getId() + 'BackendLiveSearchStore');
+               if (!this.store) {
+                       this.store = Ext.create('Ext.data.Store', {
+                               model: 'TYPO3.BackendLiveSearch.Model',
+                               proxy: {
+                                       type: 'direct',
+                                       directFn: this.dataProvider.find,
+                                       reader: {
+                                               type: 'json',
+                                               idProperty: 'type',
+                                               root: 'searchItems'
+                                       }
+                               },
+                               storeId: this.getId() + 'BackendLiveSearchStore'
+                       });
+               }
+               this.listConfig.loadingText = this.loadingText;
+               this.callParent();
        },
+       /**
+        * Create the list of search results
+        *
+        * @return Object{TYPO3.BackendLiveSearch.BoundList}
+        */
+       createPicker: function() {
+               var me = this,
+                       picker,
+                       menuCls = Ext.baseCSSPrefix + 'menu',
+                       opts = Ext.apply({
+                               pickerField: me,
+                               selModel: {
+                                       mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
+                               },
+                               floating: true,
+                               hidden: true,
+                               ownerCt: me.ownerCt,
+                               cls: me.el.up('.' + menuCls) ? menuCls : '',
+                               store: me.store,
+                               displayField: me.displayField,
+                               focusOnToFront: false,
+                               pageSize: 0,
+                               tpl: me.tpl
+                       }, me.listConfig, me.defaultListConfig);
+
+               picker = me.picker = Ext.create('TYPO3.BackendLiveSearch.BoundList', opts);
+
+               me.mon(picker, {
+                       itemclick: me.onItemClick,
+                       refresh: me.onListRefresh,
+                       scope: me
+               });
 
-       initList : function () {
-               TYPO3.BackendLiveSearch.superclass.initList.apply(this, arguments);
-               var cls = 'x-combo-list';
-
-                       // Track whether the hovering over the results list or not, to aid in detecting iframe clicks.
-               this.mon(this.list, 'mouseover', function() {this.listHovered = true;}, this);
-               this.mon(this.list, 'mouseout', function() {this.listHovered = false; }, this);
-
-               /**
-                * Create bottom Toolbar to the result layer
-                */
-               this.footer = this.list.createChild({cls:cls+'-ft'});
-
-               this.pageTb = new Ext.Toolbar({
-                       renderTo:this.footer,
-                       height: 30,
-                       items: [{
-                               xtype: 'tbfill',
-                               autoWidth : true
-                       },{
-                               xtype: 'button',
-                               text: TYPO3.LLL.liveSearch.showAllResults,
-                               arrowAlign : 'right',
-                               shadow: false,
-                               icon : '../typo3/sysext/t3skin/icons/module_web_list.gif',
-                               listeners : {
-                                       scope : this,
-                                       click : function () {
-                                                       // go to db_list.php and search for given search value
-                                                       // @todo the current selected page ID from the page tree is required, also we need the
-                                                       // values of $GLOBALS['BE_USER']->returnWebmounts() to search only during the allowed pages
-                                               TYPO3.ModuleMenu.App.showModule('web_list', this.getSearchResultsUrl(this.getValue()));
-                                               this.collapse();
-                                       }
-                               }
-                       }]
+               me.mon(picker.getSelectionModel(), {
+                       'beforeselect': me.onBeforeSelect,
+                       'beforedeselect': me.onBeforeDeselect,
+                       'selectionchange': me.onListSelectionChange,
+                       scope: me
                });
-               this.assetHeight += this.footer.getHeight();
-       },
 
-       initQuery : function(){
-               TYPO3.BackendLiveSearch.superclass.initQuery.apply(this, arguments);
-               this.removeHelp();
+               return picker;
        },
-       initHelp : function () {
-               if(!this.helpList){
+       /**
+        * Empty the search field, give it focus and collapse the results list when the trigger is clicked
+        */
+       onTriggerClick: function () {
+               this.reset();
+               this.focus();
+               this.collapse();
+       },
+       /**
+        * Add a help layer when the field is focused while empty
+        */
+       initHelp: function () {
+               if (!this.helpList){
                        var cls = 'search-list-help';
-
-                       this.helpList = new Ext.Layer({
-                               parentEl: this.getListParent(),
+                       this.helpList = Ext.create('Ext.Layer', {
+                               parentEl: this.getEl(),
                                shadow: this.shadow,
-                               cls: [cls, this.listClass].join(' '),
-                               constrain:false
+                               cls: [this.listConfig.cls, cls].join(' '),
+                               constrain: false
                        });
-
-                               // Track whether the hovering over the help list or not, to aid in detecting iframe clicks.
-                       this.mon(this.helpList, 'mouseover', function() {this.listHovered = true;}, this);
-                       this.mon(this.helpList, 'mouseout', function() {this.listHovered = false; }, this);
-
-                       var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
-                       this.helpList.setSize(lw);
+                       var helpListWidth = this.listConfig.width;
+                       this.helpList.setSize(helpListWidth);
+                               // Keep the focus on the input field so that the blur event is triggered when another iframe is clicked
+                       this.helpList.on('mouseout', function () { this.focus(); }, this);
                        this.helpList.swallowEvent('mousewheel');
-                       if(this.syncFont !== false){
-                               this.helpList.setStyle('font-size', this.el.getStyle('font-size'));
-                       }
-
-                       this.innerHelpList = this.helpList.createChild({cls:cls+'-inner'});
-                       this.mon(this.innerHelpList, 'mouseover', this.onViewOver, this);
-                       this.mon(this.innerHelpList, 'mousemove', this.onViewMove, this);
-                       this.innerHelpList.setWidth(lw - this.helpList.getFrameWidth('lr'));
-
-                       if(!this.helpTpl){
-                               this.helpTpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
-                        }
-
-                       /**
-                       * The {@link Ext.DataView DataView} used to display the ComboBox's options.
-                       * @type Ext.DataView
-                       */
-                       this.helpView = new Ext.DataView({
-                               applyTo: this.innerHelpList,
-                               tpl: this.helpTpl,
-                               singleSelect: true,
-                               selectedClass: this.selectedClass,
-                               itemSelector: this.itemSelector || '.' + cls + '-item',
-                               emptyText: this.listEmptyText
-                       });
-
+                       this.helpList.setStyle('font-size', this.getEl().getStyle('font-size'));
                        this.helpList.createChild({
                                cls: cls + '-content',
                                // @todo Can we grab this content via ExtDirect?
                                html: '<strong>' + this.helpTitle + '</strong><p>' + TYPO3.LLL.liveSearch.helpDescription + '<br /> ' + TYPO3.LLL.liveSearch.helpDescriptionPages + '</p>'
                        });
-
-                       this.helpList.alignTo(this.wrap, this.listAlign);
+                       this.helpList.alignTo(this.getEl(), this.pickerAlign);
                        this.helpList.show();
                }
        },
-
-       removeHelp : function() {
+       /**
+        * Remove the help layer when a query search is being submitted
+        */
+       removeHelp: function () {
                if (this.helpList) {
                        this.helpList.destroy();
                        delete this.helpList;
                }
        },
-
-       onFocus : function() {
-               TYPO3.BackendLiveSearch.superclass.onFocus.apply(this, arguments);
-
-               // If search is blank, show the help on focus. Otherwise, show last results
-               if (this.getValue() == '') {
-                       this.initHelp();
-               } else {
-                       this.expand();
-               }
-       },
-
        /**
-        * Fired when search results are clicked. We do not want the search result
-        * appear so we always set doFocus = false
+        * Hide the trigger and clear the search field
         */
-       onViewClick : function(doFocus){
-               doFocus = false;
-               TYPO3.BackendLiveSearch.superclass.onViewClick.apply(this, arguments);
-       },
-
-       postBlur : function() {
-               TYPO3.BackendLiveSearch.superclass.postBlur.apply(this, arguments);
-               this.removeHelp();
-       },
-
-       getTriggerWidth : function() {
-               // Trigger is inset, so width used in calculations is 0
-               return 0;
-       },
-
-       reset : function() {
-           this.originalValue = this.emptyText;
+       reset: function () {
                this.setHideTrigger(true);
-               TYPO3.BackendLiveSearch.superclass.reset.apply(this, arguments);
+               this.callParent();
        },
-
-       getSearchResultsUrl : function(searchTerm) {
+       /**
+        * Build the url params of the search results
+        *
+        * @return      String
+        */
+       getSearchResultsUrl: function (searchTerm) {
                return 'id=' + this.searchResultsPid + '&search_levels=4&search_field=' + searchTerm;
        },
-
-       handleBlur : function(e) {
-
-               if (!this.listHovered) {
-                       this.hasFocus = false;
-                       if (this.getValue() == '') {
+       /**
+        * If the mouse is not over the list and the field lost focus to another iframe
+        */
+       handleBlur: function (event) {
+               if (this.destroying) {
+                       return;
+               }
+               if ((this.getPicker().el && !this.getPicker().el.hasCls('live-search-list-over')) || this.helpList) {
+                       if (!this.getValue()) {
                                this.reset();
-                       }
-                       this.postBlur();
+                       };
+                       this.inputEl.removeCls(this.focusCls);
+                       this.hasFocus = false;
+                       this.fireEvent('blur', this);
                }
-
        }
 });
-
-var TYPO3LiveSearch;
-
+/**
+ * Create the live search box when Ext is ready
+ */
 Ext.onReady(function() {
-       TYPO3LiveSearch = new TYPO3.BackendLiveSearch({
+       TYPO3.BackendLiveSearch.Box = Ext.create('TYPO3.BackendLiveSearch.ComboBox', {
                dataProvider: TYPO3.LiveSearchActions.ExtDirect,
-               title: TYPO3.LLL.liveSearch.title,
                helpTitle: TYPO3.LLL.liveSearch.helpTitle,
                emptyText: TYPO3.LLL.liveSearch.emptyText,
                loadingText: TYPO3.LLL.liveSearch.loadingText,
-               listEmptyText: TYPO3.LLL.liveSearch.listEmptyText,
+               renderTo: Ext.get('live-search-box'),
                searchResultsPid: TYPO3.configuration.firstWebmountPid
        });
-
-       TYPO3LiveSearch.applyToMarkup(Ext.get('live-search-box'));
-
                // Add a blur event listener outside the ExtJS widget to handle clicks in iframes also.
-       Ext.get('live-search-box').on('blur', TYPO3LiveSearch.handleBlur, TYPO3LiveSearch);
+       Ext.get('live-search-box').down('input').on('blur', TYPO3.BackendLiveSearch.Box.handleBlur, TYPO3.BackendLiveSearch.Box);
 });
index 33ca93b..fa2fccc 100644 (file)
@@ -27,9 +27,8 @@
 /**
  * AJAX login refresh box
  */
-Ext.namespace('Ext.ux.TYPO3');
-
-Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
+Ext.define('Ext.ux.TYPO3.loginRefresh', {
+       extend: 'Ext.util.Observable',
        locked: 0,
        interval: 60,
 
@@ -48,7 +47,7 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                                        },
                                        method: "GET",
                                        success: function(response, options) {
-                                               var result = Ext.util.JSON.decode(response.responseText);
+                                               var result = Ext.JSON.decode(response.responseText);
                                                if (result.login.locked) {
                                                        this.locked = 1;
                                                        Ext.MessageBox.show({
@@ -84,11 +83,11 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                        scope: this
                };
                this.startTimer();
-               Ext.ux.TYPO3.loginRefresh.superclass.constructor.call(this, config);
+               this.callParent([config]);
        },
 
        initComponents: function() {
-               var loginPanel = new Ext.FormPanel({
+               var loginPanel = Ext.create('Ext.form.Panel', {
                        url: "ajax.php",
                        id: "loginform",
                        title: TYPO3.LLL.core.refresh_login_title,
@@ -141,7 +140,7 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                                }
                        }]
                });
-               this.loginRefreshWindow = new Ext.Window({
+               this.loginRefreshWindow = Ext.create('Ext.window.Window', {
                        id: "loginformWindow",
                        width: 450,
                        autoHeight: true,
@@ -159,13 +158,13 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                        }
                });
 
-               var progressControl = new Ext.ProgressBar({
+               var progressControl = Ext.create('Ext.ProgressBar', {
                        autoWidth: true,
                        autoHeight: true,
                        value: 30
                });
 
-               this.progressWindow = new Ext.Window({
+               this.progressWindow = Ext.create('Ext.window.Window', {
                        closable: false,
                        resizable: false,
                        draggable: false,
@@ -262,18 +261,18 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
        },
 
        startTimer: function() {
-               Ext.TaskMgr.start(this.loadingTask);
+               Ext.TaskManager.start(this.loadingTask);
        },
 
        stopTimer: function() {
-               Ext.TaskMgr.stop(this.loadingTask);
+               Ext.TaskManager.stop(this.loadingTask);
        },
 
        submitForm: function(challenge) {
                var form = Ext.getCmp("loginform").getForm();
                var fields = form.getValues();
                if (fields.p_field === "") {
-                       Ext.Msg.alert(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_emptyPassword);
+                       Ext.MessageBox.alert(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_emptyPassword);
                } else {
                        if (TS.securityLevel === "superchallenged") {
                                fields.p_field = MD5(fields.p_field);
@@ -301,14 +300,14 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                                        TYPO3.loginRefresh.startTimer();
                                },
                                failure: function(form, action) {
-                                       var result = Ext.util.JSON.decode(action.response.responseText).login;
+                                       var result = Ext.JSON.decode(action.response.responseText).login;
                                        if (result.success) {
                                                // User is logged in
                                                Ext.getCmp("loginformWindow").hide();
                                                TYPO3.loginRefresh.startTimer();
                                        } else {
                                                // TODO: add failure to notification system instead of alert
-                                               Ext.Msg.alert(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_failed_message);
+                                               Ext.MessageBox.alert(TYPO3.LLL.core.refresh_login_failed, TYPO3.LLL.core.refresh_login_failed_message);
                                        }
                                }
                        });
@@ -325,7 +324,7 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
                                },
                                method: 'GET',
                                success: function(response) {
-                                       var result = Ext.util.JSON.decode(response.responseText);
+                                       var result = Ext.JSON.decode(response.responseText);
                                        if (result.challenge) {
                                                Ext.getCmp('challenge').value = result.challenge;
                                                TYPO3.loginRefresh.submitForm(result.challenge);
@@ -340,10 +339,9 @@ Ext.ux.TYPO3.loginRefresh = Ext.extend(Ext.util.Observable, {
 });
 
 
-
 /**
  * Initialize login expiration warning object
  */
 Ext.onReady(function() {
-       TYPO3.loginRefresh = new Ext.ux.TYPO3.loginRefresh();
+       TYPO3.loginRefresh = Ext.create('Ext.ux.TYPO3.loginRefresh');
 });
index ccaa881..37aa9f3 100644 (file)
@@ -36,20 +36,71 @@ Ext.ns('TYPO3', 'ModuleMenu');
 
 TYPO3.ModuleMenu = {};
 
-TYPO3.ModuleMenu.Store = new Ext.data.JsonStore({
-       storeId: 'ModuleMenuStore',
-       root: 'root',
-       fields: [
-               {name: 'index', type: 'int', mapping: 'sub.index'},
-               {name: 'key', type: 'string'},
-               {name: 'label', type: 'string'},
-               {name: 'menuState', type: 'int'},
-               {name: 'subitems', type: 'int'},
-               'sub'
-       ],
-       url: 'ajax.php?ajaxID=ModuleMenu::getData',
-       baseParams: {
-               'action': 'getModules'
+Ext.define('TYPO3.model.ModuleMenu', {
+       extend: 'Ext.data.Model',
+       idProperty: 'index',
+       fields: [{
+                       name: 'index',
+                       type: 'int',
+               },{
+                       name: 'key',
+                       type: 'string'
+               },{
+                       name: 'name',
+                       type: 'string'
+               },{
+                       name: 'label',
+                       type: 'string'
+               },{
+                       name: 'description',
+                       type: 'string'
+               },{
+                       name: 'icon',
+                       type: 'string'
+               },{
+                       name: 'menuState',
+                       type: 'int'
+               },{
+                       name: 'navigationComponentId',
+                       type: 'string'
+               },{
+                       name: 'navigationFrameScript',
+                       type: 'string'
+               },{
+                       name: 'navframe',
+                       type: 'string'
+               },{
+                       name: 'navigationFrameScriptParam',
+                       type: 'string'
+               },{
+                       name: 'link',
+                       type: 'string'
+               },{
+                       name: 'originalLink',
+                       type: 'string'
+               },{
+                       name: 'subitems',
+                       type: 'int'
+       }],
+       associations: [{
+                       name: 'sub',
+                       type: 'hasMany',
+                       model: 'TYPO3.model.ModuleMenu'
+       }]
+});
+TYPO3.ModuleMenu.Store = Ext.create('Ext.data.Store', {
+       storeId: 'moduleMenuStore',
+       model: 'TYPO3.model.ModuleMenu',
+       proxy: {
+               type: 'ajax',
+               url: 'ajax.php?ajaxID=ModuleMenu::getData',
+               extraParams: {
+                       'action': 'getModules'
+               },
+               reader: {
+                   type: 'json',
+                   root: 'root'
+               }
        },
        listeners: {
                beforeload: function(store) {
@@ -64,16 +115,9 @@ TYPO3.ModuleMenu.Store = new Ext.data.JsonStore({
        isLoaded: function() {
                return this.loaded;
        }
-
 });
 
-TYPO3.ModuleMenu.Template = new Ext.XTemplate(
-               '<div id="typo3-docheader">',
-               '       <div id="typo3-docheader-row1">',
-               '               <div class="buttonsleft"></div>',
-               '               <div class="buttonsright"></div>',
-               '       </div>',
-               '</div>',
+TYPO3.ModuleMenu.Template = Ext.create('Ext.XTemplate',
                '<ul id="typo3-menu">',
                '<tpl for=".">',
                '       <li class="menuSection" id="{key}">',
@@ -111,99 +155,144 @@ TYPO3.ModuleMenu.App = {
        init: function() {
                TYPO3.ModuleMenu.Store.load({
                        scope: this,
-                       callback: function(records, options) {
+                       callback: function(records, operation, success) {
                                this.renderMenu(records);
-                               if (top.startInModule) {
-                                       this.showModule(top.startInModule[0], top.startInModule[1]);
-                               } else {
-                                       this.loadFirstAvailableModule();
-                               }
                        }
                });
        },
 
        renderMenu: function(records) {
                TYPO3.Backend.ModuleMenuContainer.removeAll();
+               TYPO3.Backend.ModuleMenuContainer.addDocked({
+                       cls: 'typo3-module-panel-toolbar',
+                       height: 22,
+                       html: '<div id="typo3-docheader">' +
+                               '       <div id="typo3-docheader-row1">' +
+                               '               <div class="buttonsleft"></div>' +
+                               '               <div class="buttonsright"></div>' +
+                               '       </div>' +
+                               '</div>',
+                       xtype: 'component'
+               });
                TYPO3.Backend.ModuleMenuContainer.add({
                        xtype: 'dataview',
-                       animCollapse: true,
                        store: TYPO3.ModuleMenu.Store,
                        tpl: TYPO3.ModuleMenu.Template,
                        singleSelect: true,
                        itemSelector: 'li.submodule',
-                       overClass: 'x-view-over',
-                       selectedClass: 'highlighted',
-                       autoHeight: true,
+                       overItemCls: 'x-view-over',
+                       trackOver: true,
+                       selectedItemCls: 'highlighted',
                        itemId: 'modDataView',
-                       tbar: [{text: 'test'}],
+                               // ExtJS is not really ready to handle nested template...
+                       updateIndexes: function(startIndex, endIndex) {
+                               var ns = this.all.elements,
+                                       records = this.store.getRange(),
+                                       index = 0, i, j, m, n, record, items;
+                               startIndex = startIndex || 0;
+                               endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
+                               for (i = 0, n = records.length -1; i < n; i++) {
+                                       items = records[i].getAssociatedData().sub;
+                                       if (items.length) {
+                                               for (j = 0, m = items.length - 1; j < m; j++) {
+                                                       if (startIndex <= index && index <= endIndex) {
+                                                               ns[index].viewIndex = index;
+                                                               ns[index].viewRecordId = records[i].internalId;
+                                                               if (!ns[index].boundView) {
+                                                                       ns[index].boundView = this.id;
+                                                               }
+                                                       }
+                                                       index++;
+                                               }
+                                       }
+                               }
+                       },
                        listeners: {
-                               click: function(view, index, node, event) {
-                                       var el = Ext.fly(node);
-                                       if (el.hasClass('submodule')) {
-                                               TYPO3.ModuleMenu.App.showModule(el.getAttribute('id'));
+                               viewready: {
+                                       fn: function () {
+                                               if (top.startInModule) {
+                                                       this.showModule(top.startInModule[0], top.startInModule[1]);
+                                               } else {
+                                                       this.loadFirstAvailableModule();
+                                               }
+                                       },
+                                       scope: this
+                               },
+                                       // The selection of this view is on the main module. We don't need this
+                               beforeselect: {
+                                       fn: function (view) {
+                                               return false;
                                        }
                                },
-                               containerclick: function(view, event) {
-                                       var item = event.getTarget('li.menuSection', view.getEl());
-                                       if (item) {
-                                               var el = Ext.fly(item);
-                                               var id = el.getAttribute('id');
-                                               var section = el.first('div'), state;
-                                               if (section.hasClass('expanded')) {
-                                                       state = true;
-                                                       section.removeClass('expanded').addClass('collapsed');
-                                                       el.first('ul').slideOut('t', {
-                                                               easing: 'easeOut',
-                                                               duration: .2,
-                                                               remove: false,
-                                                               useDisplay: true
-                                                       });
-
-                                               } else {
-                                                       state = false;
-                                                       section.removeClass('collapsed').addClass('expanded');
-                                                       el.first('ul').slideIn('t', {
-                                                               easing: 'easeIn',
-                                                               duration: .2,
-                                                               remove: false,
-                                                               useDisplay: true
-                                                       });
+                               itemclick: {
+                                       fn: function(view, record, node, index, event) {
+                                               var moduleName = node.getAttribute('id');
+                                               if (moduleName) {
+                                                       TYPO3.ModuleMenu.App.showModule(moduleName);
                                                }
-                                               // save menu state
-                                               Ext.Ajax.request({
-                                                       url: 'ajax.php?ajaxID=ModuleMenu::saveMenuState',
-                                                       params: {
-                                                               'menuid': 'modmenu_' + id,
-                                                               'state': state
-                                                       }
-                                               });
                                        }
-                                       return false;
                                },
-                               scope: this
+                               containerclick: {
+                                       fn: function(view, event) {
+                                               var item = event.getTarget('li.menuSection', view.getEl());
+                                               if (item) {
+                                                       var el = Ext.get(item);
+                                                       var id = el.getAttribute('id');
+                                                       var section = el.first('div'), state;
+                                                       if (section.hasCls('expanded')) {
+                                                               state = true;
+                                                               section.removeCls('expanded').addCls('collapsed');
+                                                               el.first('ul').slideOut('t', {
+                                                                       easing: 'easeOut',
+                                                                       duration: .2,
+                                                                       remove: false,
+                                                                       useDisplay: true
+                                                               });
+                                                       } else {
+                                                               state = false;
+                                                               section.removeCls('collapsed').addCls('expanded');
+                                                               el.first('ul').slideIn('t', {
+                                                                       easing: 'easeIn',
+                                                                       duration: .2,
+                                                                       remove: false,
+                                                                       useDisplay: true
+                                                               });
+                                                       }
+                                                       // save menu state
+                                                       Ext.Ajax.request({
+                                                               url: 'ajax.php?ajaxID=ModuleMenu::saveMenuState',
+                                                               params: {
+                                                                       'menuid': 'modmenu_' + id,
+                                                                       'state': state
+                                                               }
+                                                       });
+                                               }
+                                               return false;
+                                       }
+                               }
                        }
                });
-               TYPO3.Backend.ModuleMenuContainer.doLayout();
        },
-
        getRecordFromIndex: function(index) {
-               var i, record;
+               var i, record, items;
                for (i = 0; i < TYPO3.ModuleMenu.Store.getCount(); i++) {
                        record = TYPO3.ModuleMenu.Store.getAt(i);
-                       if (index < record.data.subitems) {
-                               return record.data.sub[index];
+                       items = record.getAssociatedData().sub;
+                       if (index < record.get('subitems')) {
+                               return items[index];
                        }
-                       index -= record.data.subitems;
+                       index -= record.get('subitems');
                }
        },
 
        getRecordFromName: function(name) {
-               var i, j, record;
-               for (i = 0; i < TYPO3.ModuleMenu.Store.getCount(); i++) {
+               var i, j, recordsCount, itemsCount, record, items;
+               for (i = 0, recordsCount = TYPO3.ModuleMenu.Store.getCount(); i < recordsCount; i++) {
                        record = TYPO3.ModuleMenu.Store.getAt(i);
-                       for (j = 0; j < record.data.subitems; j++) {
-                               if (record.data.sub[j].name === name) {
-                                       return record.data.sub[j];
+                       items = record.getAssociatedData().sub;
+                       for (j = 0, itemsCount = record.get('subitems'); j < itemsCount; j++) {
+                               if (items[j].name === name) {
+                                       return items[j];
                                }
                        }
                }
@@ -215,7 +304,6 @@ TYPO3.ModuleMenu.App = {
 
                params = this.includeId(mod, params);
                var record = this.getRecordFromName(mod);
-
                if (record) {
                        this.loadModuleComponents(record, params);
                } else {
@@ -236,7 +324,7 @@ TYPO3.ModuleMenu.App = {
                                // Store is empty, something went wrong
                        TYPO3.Flashmessage.display(TYPO3.Severity.error, 'Module loader', 'No module found. If this is a temporary error, please reload the Backend!', 50000);
                } else {
-                       mod = TYPO3.ModuleMenu.Store.getAt(0).data.sub[0];
+                       mod = TYPO3.ModuleMenu.Store.getAt(0).getAssociatedData().sub[0];
                        this.loadModuleComponents(mod, params);
                }
        },
@@ -244,28 +332,29 @@ TYPO3.ModuleMenu.App = {
        loadModuleComponents: function(record, params) {
                var mod = record.name;
                if (record.navigationComponentId) {
-                               this.loadNavigationComponent(record.navigationComponentId);
-                               TYPO3.Backend.NavigationDummy.hide();
-                               TYPO3.Backend.NavigationIframe.getEl().parent().setStyle('overflow', 'auto');
-                       } else if (record.navframe || record.navigationFrameScript) {
-                               TYPO3.Backend.NavigationDummy.hide();
-                               TYPO3.Backend.NavigationContainer.show();
-                               this.loadNavigationComponent('typo3-navigationIframe');
-                               this.openInNavFrame(record.navigationFrameScript || record.navframe, record.navigationFrameScriptParam);
-                               TYPO3.Backend.NavigationIframe.getEl().parent().setStyle('overflow', 'hidden');
-                       } else {
-                               TYPO3.Backend.NavigationContainer.hide();
-                               TYPO3.Backend.NavigationDummy.show();
-                       }
-                       this.openInContentFrame(record.originalLink, params);
-                       this.loadedModule = mod;
-                       this.highlightModuleMenuItem(mod);
+                       this.loadNavigationComponent(record.navigationComponentId);
+                       TYPO3.Backend.NavigationDummy.hide();
+                       TYPO3.Backend.NavigationIframe.getEl().parent().setStyle('overflow', 'auto');
+               } else if (record.navframe || record.navigationFrameScript) {
+                       TYPO3.Backend.NavigationDummy.hide();
+                       TYPO3.Backend.NavigationContainer.show();
+                       this.loadNavigationComponent('typo3-navigationIframe');
+                       this.openInNavFrame(record.navigationFrameScript || record.navframe, record.navigationFrameScriptParam);
+                       TYPO3.Backend.NavigationIframe.getEl().parent().setStyle('overflow', 'hidden');
+               } else {
+                       TYPO3.Backend.NavigationContainer.hide();
+                       TYPO3.Backend.NavigationDummy.show();
+               }
+                       // Set internal state
+               this.loadedModule = mod;
+               this.highlightModuleMenuItem(mod);
+               this.openInContentFrame(record.originalLink, params);
 
-                               // compatibility
-                       top.currentSubScript = record.originalLink;
-                       top.currentModuleLoaded = mod;
+                       // compatibility
+               top.currentSubScript = record.originalLink;
+               top.currentModuleLoaded = mod;
 
-                       TYPO3.Backend.doLayout();
+               TYPO3.Backend.doLayout();
        },
 
        includeId: function(mod, params) {
@@ -333,7 +422,11 @@ TYPO3.ModuleMenu.App = {
        },
 
        highlightModuleMenuItem: function(module, mainModule) {
-               TYPO3.Backend.ModuleMenuContainer.getComponent('modDataView').select(module, false, false);
+               var highlighted = Ext.fly('typo3-menu').query('li.highlighted');
+               Ext.Array.each(highlighted, function(el) {
+                       Ext.fly(el).removeCls('highlighted');
+               });
+               Ext.fly(module).addCls('highlighted');
        },
 
        relativeUrl: function(url) {
@@ -343,7 +436,7 @@ TYPO3.ModuleMenu.App = {
        refreshMenu: function() {
                TYPO3.ModuleMenu.Store.load({
                        scope: this,
-                       callback: function(records, options) {
+                       callback: function(records, operation, success) {
                                this.renderMenu(records);
                                if (this.loadedModule) {
                                        this.highlightModuleMenuItem(this.loadedModule);
index c7aadaa..e9c3a55 100644 (file)
@@ -49,7 +49,7 @@ var PagetreeFilterMenu = Class.create({
 
                toolbarItem.blur();
 
-               if (toolbarItem.hasClass('active')) {
+               if (toolbarItem.hasCls('active')) {
                        treeFilterBox.fadeOut();
                        TYPO3PageTreeFilter.resetSearchField();
                } else {
@@ -57,7 +57,7 @@ var PagetreeFilterMenu = Class.create({
                        treeFilterItem.focus();
                }
 
-               toolbarItem.toggleClass('active');
+               toolbarItem.toggleCls('active');
 
        }
 });
index f1a0c0e..39c2087 100644 (file)
@@ -24,7 +24,7 @@ div#typo3-docheader-row1 {
 }
 
 div#typo3-docheader-row2 {
-       height: 21px;
+       height: 27px;
        padding-top: 6px;
 }
 
diff --git a/typo3/sysext/t3skin/stylesheets/structure/toolbar_livesearch.css b/typo3/sysext/t3skin/stylesheets/structure/toolbar_livesearch.css
new file mode 100644 (file)
index 0000000..be27e5a
--- /dev/null
@@ -0,0 +1,42 @@
+/* - - - - - - - - - - - - - - - - - - - - -
+Backend  Live Search
+- - - - - - - - - - - - - - - - - - - - - */
+.live-search-results {
+       margin-top: 2px;
+}
+
+.live-search-results .t3-icon-toolbar-menu-search {
+       position: absolute;
+       z-index: 3000;
+       top: 0;
+       margin: 4px 3px 3px 3px;
+}
+
+.live-search-results .x-form-field {
+       height: 18px;
+}
+
+.live-search-results .t3-icon-input-clear {
+       cursor: pointer;
+       position: absolute;
+       top: 2px;
+       right: 3px;
+}
+
+.live-search-list {
+       width: 315px !important;
+}
+
+.live-search-list .search-list-help-content {
+       margin: 5px;
+       height: 100%;
+}
+
+.live-search-list .search-item-type {
+       width: 105px;
+}
+
+.live-search-list .search-item-content {
+       width: 195px;
+}
+
index 0e32a0c..e813115 100644 (file)
@@ -5,6 +5,7 @@ Topbar (whole upper area), containts Logo and toolbar
 
 #typo3-topbar {
        z-index: 200;
+       overflow: visible !important;
 }
 
 #typo3-topbar div {
index 6ad1455..4a6e6cf 100644 (file)
@@ -17,6 +17,7 @@ Record editing (alt_doc.php)
 
 div#typo3-docheader-row1 {
        background-color: #585858;
+       border: none;
 }
 
 div#typo3-docheader-row2 {
index 14fab06..1f3d860 100644 (file)
@@ -2,24 +2,14 @@
 Backend  Live Search
 - - - - - - - - - - - - - - - - - - - - - */
 
-.live-search-results .t3-icon-toolbar-menu-search {
-       position: absolute;
-       z-index: 3000;
-       top: 0;
-       margin: 3px;
-}
-
-.t3-icon-input-clear {
-       cursor: pointer;
-       position: absolute;
-       top: 0px;
-       right: 20px;
+.live-search-results .x-form-field {
+       border: none;
+       line-height: 18px;
+       padding-left: 20px;
 }
 
-#live-search-box {
-       padding-left: 20px;
-       width: 180px;
-       border: none;
+.live-search-results .x-form-trigger {
+       border-bottom: none;
 }
 
 .live-search-list {
@@ -27,37 +17,24 @@ Backend  Live Search
        border: none;
 }
 
-.live-search-list .x-combo-list {
-       background-color: white;
-}
-
-.live-search-list .x-combo-list-inner {
-       padding-bottom: 5px;
+.live-search-list .live-search-list-title {
+       text-align: center;
 }
 
-.live-search-list .x-combo-list-hd {
-       background: none;
-       border: none;
-       margin-left: 110px;
-       color: #ddd;
-}
-
-.search-list-help-content {
-       margin: 5px;
-       height: 100%;
-       padding: 0.6em 0.6em 0.6em 2.6em;
-       background-repeat: no-repeat;
+.live-search-list .search-list-help-content {
+       background-color: #ddeef9;
        background-position: 0.5em 0.7em;
+       background-repeat: no-repeat;
        border: 1px solid;
-       color: #000000;
-
-       background-color: #ddeef9;
        border-color: #8aafc4;
+       color: #000000;
+       padding: 0.6em 0.6em 0.6em 2.6em;
 }
 
 .live-search-list .search-item-type {
        border-right: 1px solid #ddd;
        padding: 2px 5px 2px 0;
+       text-align: right;
 }
 
 .live-search-list .search-item-content {