Added feature #15588: Extend TYPO3 DebugConsole
authorSteffen Kamper <info@sk-typo3.de>
Mon, 6 Sep 2010 12:10:49 +0000 (12:10 +0000)
committerSteffen Kamper <info@sk-typo3.de>
Mon, 6 Sep 2010 12:10:49 +0000 (12:10 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@8764 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/js/extjs/ux/ext.ux.tabclosemenu.js
typo3/backend.php
typo3/js/extjs/debugPanel.js
typo3/js/extjs/viewportConfiguration.js
typo3/sysext/lang/locallang_core.xml
typo3/sysext/setup/ext_tables.php
typo3/sysext/setup/mod/locallang.xml
typo3/template.php

index f901aef..1f765f5 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,6 @@
 2010-09-06  Steffen Kamper  <steffen@typo3.org>
 
+       * Added feature #15588: Extend TYPO3 DebugConsole
        * Fixed bug #15589: Move debug functions to own utility class
 
 2010-09-05  Steffen Gebert  <steffen@steffen-gebert.de>
index 9c29754..3893368 100644 (file)
@@ -40,6 +40,12 @@ Ext.ux.TabCloseMenu = Ext.extend(Object, {
      */
     closeAllTabsText: 'Close All Tabs',
     
+    /**
+        * @cfg {Array} custom menu entries
+        */
+       customMenuEntries: [],
+
+    
     constructor : function(config){
         Ext.apply(this, config || {});
     },
@@ -114,6 +120,12 @@ Ext.ux.TabCloseMenu = Ext.extend(Object, {
                     handler: this.onCloseAll
                 });
             }
+            if (this.customMenuEntries.length) {
+               this.customMenuEntries.each(function(item) {
+                       items.push(item);
+               });
+            }
+            
             this.menu = new Ext.menu.Menu({
                 items: items
             });
index c62f75c..3e7c2f3 100644 (file)
@@ -102,9 +102,15 @@ class TYPO3backend {
 
                $this->pageRenderer->addExtOnReadyCode(
                        'TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
-                       ',
+                       if (typeof console === "undefined") {
+                               console = TYPO3.Backend.DebugConsole;
+                       }',
                        TRUE
                );
+               $this->pageRenderer->addJsInlineCode(
+                       'consoleOverrideWithDebugPanel',
+                       '//already done'
+               );
                $this->pageRenderer->addExtDirectCode();
 
                        // add default BE javascript
@@ -385,6 +391,7 @@ class TYPO3backend {
                        'topBarHeight' => (isset($GLOBALS['TBE_STYLES']['dims']['topFrameH']) ? intval($GLOBALS['TBE_STYLES']['dims']['topFrameH']) : 30),
                        'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? intval($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) : FALSE,
                        'listModulePath' => t3lib_extMgm::isLoaded('list') ? t3lib_extMgm::extRelPath('list') . 'mod1/' : '',
+                       'debugInWindow' => $GLOBALS['BE_USER']->uc['debugInWindow'] ? 1 : 0,
                );
                $t3LLLcore = array(
                        'waitTitle' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_logging_in') ,
@@ -408,6 +415,7 @@ class TYPO3backend {
                        'tabs_closeAll' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeAll'),
                        'tabs_closeOther' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeOther'),
                        'tabs_close' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.close'),
+                       'tabs_openInBrowserWindow' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.openInBrowserWindow'),
                        'donateWindow_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.title'),
                        'donateWindow_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.message'),
                        'donateWindow_button_donate' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_donate'),
index 3344ec0..b373c1d 100644 (file)
@@ -53,6 +53,14 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
        tabGroups: new Ext.util.MixedCollection(),
 
        /**
+        * Indicator if the debug panel is wrapped inside a debug panel
+        * @see addTabWidget()
+        * 
+        * @var boolean
+        */
+       isTabChildren: false,
+
+       /**
         * Initializes the widget and merges our defaults with the user-defined ones. The
         * user-defined settings are preferred.
         *
@@ -71,21 +79,81 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                        plugins: new Ext.ux.TabCloseMenu({
                                closeTabText: TYPO3.LLL.core.tabs_close,
                                closeOtherTabsText: TYPO3.LLL.core.tabs_closeOther,
-                               closeAllTabsText: TYPO3.LLL.core.tabs_closeAll
+                               closeAllTabsText: TYPO3.LLL.core.tabs_closeAll,
+                               customMenuEntries: [
+                                       '-',
+                                       {
+                                               itemId: 'openInBrowserWindow',
+                                               text: TYPO3.LLL.core.tabs_openInBrowserWindow,
+                                               scope: this,
+                                               handler: function() {
+                                                       var tab = this.plugins.active;
+                                                       var group = '', content = '';
+
+                                                       if (tab.ownerCt.ownerCt instanceof Ext.TabPanel) {
+                                                               group = tab.ownerCt.title;
+                                                               content = tab.body.dom.innerHTML;
+                                                       } else {
+                                                               group = tab.title;
+                                                               tab.items.each(function(item) {
+                                                                       content += item.body.dom.innerHTML;
+                                                               });
+                                                       }
+
+                                                       this.openBrowserWindow(
+                                                               tab.title,
+                                                               content,
+                                                               group
+                                                       );
+                                               }
+                                       }
+                               ]
                        })
                });
 
-                       // create a drop arrow indicator
-               this.on('render', function() {
-                       this.arrow = Ext.DomHelper.append(
-                               Ext.getBody(),
-                               '<div class="typo3-debugPanel-dragDropArrowDown">&nbsp;</div>',
-                               true
-                       );
-                       this.arrow.hide();
+                       
+               TYPO3.DebugPanel.superclass.initComponent.call(this);
+       },
+
+       /**
+        * Create a drop arrow indicator for the tab drag&drop feature while rendering
+        * the component
+        *
+        * @return void
+        */
+       onRender: function() {
+               this.arrow = Ext.DomHelper.append(
+                       Ext.getBody(),
+                       '<div class="typo3-debugPanel-dragDropArrowDown">&nbsp;</div>',
+                       true
+               );
+               this.arrow.hide();
+
+               this.on('move', function() {
+                       this.ownerCt.fireEvent('resize');
                }, this);
 
-               TYPO3.DebugPanel.superclass.initComponent.call(this);
+               TYPO3.DebugPanel.superclass.onRender.apply(this, arguments);
+       },
+       
+       /**
+        * Collapse event
+        *
+        * @return void
+        */
+       onCollapse: function() {
+               TYPO3.DebugPanel.superclass.onCollapse.apply(this, arguments);
+               this.ownerCt.fireEvent('resize');
+       },
+
+       /**
+        * Expand event
+        *
+        * @return void
+        */
+       onExpand: function() {
+               TYPO3.DebugPanel.superclass.onExpand.apply(this, arguments);
+               this.ownerCt.fireEvent('resize');
        },
 
        /**
@@ -99,7 +167,8 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
        },
 
        /**
-        * Adds a new tab
+        * Adds a new tab inside a new debug console tab or inside a new browser window if the
+        * debugInWindow configuration variable is set.
         *
         * If you need more possibilites, you should use the addTabWidget method.
         *
@@ -111,16 +180,20 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
         * @return void
         */
        addTab: function(tabContent, header, group, position) {
-               var tabWidget = new Ext.Panel({
-                       title: header,
-                       html: tabContent,
-                       border: false,
-                       autoScroll: true,
-                       closable: true,
-                       draggableTab: true
-               });
-
-               this.addTabWidget(tabWidget, group, position);
+               if (TYPO3.configuration.debugInWindow) {
+                       this.openBrowserWindow(header, tabContent, group);
+               } else {
+                       var tabWidget = new Ext.Panel({
+                               title: header,
+                               html: tabContent,
+                               border: false,
+                               autoScroll: true,
+                               closable: true,
+                               draggableTab: true
+                       });
+                       
+                       this.addTabWidget(tabWidget, group, position);
+               }
        },
 
        /**
@@ -138,13 +211,14 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
        addTabWidget: function(tabWidget, group, position) {
                if (this.hidden) {
                        this.show();
+                       this.ownerCt.fireEvent('resize');
                } else if (this.collapsed) {
                        this.expand();
                }
 
                        // Move the widget into a tab group?
                var tabGroup = this;
-               if (typeof group !== 'undefined' && group != '' && !this.isTabChildren) {
+               if (typeof group !== 'undefined' && group !== '' && !this.isTabChildren) {
                        if (this.tabGroups.indexOfKey(group) === -1) {
                                tabGroup = new TYPO3.DebugPanel({
                                        border: false,
@@ -384,6 +458,155 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, {
                                return true;
                        }
                });
+       },
+       
+       /**
+        * Opens debug output in a new browser window
+        * 
+        * @param title string
+        * @param content string
+        * @param group string
+        * @return void
+        */
+       openBrowserWindow: function(title, content, group) {
+               if (Ext.isIE6) {
+                       group = group.replace(' ', '_');
+               }
+               var newWindow = window.open('', 'TYPO3DebugWindow_' + group,
+                       '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);
+               } else {
+                       newWindow.document.writeln(
+                               '<html><head><title>Debug: ' + title + '(' + group + ')</title></head>'
+                               + '<body bgcolor=white onLoad="self.focus()">'
+                               + content
+                               + '</body></html>'
+                       );
+               }
+               newWindow.document.close()
+       },
+       
+       /**
+        * Wrapper for console.log
+        *
+        * @return void
+        */
+       log: function() {
+               this.debug(arguments[0], 'Log', 'Javascript Console');
+       },
+       
+       /**
+        * Wrapper for console.info
+        *
+        * @return void
+        */
+       info: function() {
+               this.debug(arguments[0], 'Info', 'Javascript Console');
+       },
+       
+       /**
+        * Wrapper for console.warn
+        *
+        * @return void
+        */
+       warn: function() {
+               this.debug(arguments[0], 'Warning', 'Javascript Console');
+       },
+       
+       /**
+        * Wrapper for console.error
+        *
+        * @return void
+        */
+       error: function() {
+               this.debug(arguments[0], 'Error', 'Javascript Console');
+       },
+       
+       /**
+        * Debug output from javascript
+        * 
+        * @param out mixed debug output
+        * @param header string
+        * @param group string
+        */
+       debug: function(out, header, group) {
+               var output = this.printObject(out);
+               this.addTab(output, header, group);
+       },
+       
+       /**
+        * Converts any string/array/object to a string for printing purposes
+        * 
+        * @param object object
+        * @param level integer recursion level counter (max. 3 levels)
+        * @param prefix string internal use!
+        * @return string
+        */
+       printObject: function(object, level, prefix) {
+               var result = '';
+
+               prefix = prefix || '';
+               level = level || 0;
+               if (level >= 3) {
+                       return result;
+               }
+
+               var levelPadding = '';
+               for(var j = 0; j < level + 1; ++j) {
+                       levelPadding += '    ';
+               }
+
+               if (typeof(object) === 'object') {
+                               // Array / Objects
+                       for (var item in object) {
+                               var value = object[item];
+
+                               if (typeof(value) === 'object') {
+                                       result += levelPadding + '"' + prefix + item + '" ...' + "\n";
+                                       result += this.printObject(value, level + 1, prefix + item + '.');
+                               } else {
+                                       result += levelPadding + '"' + prefix + item +
+                                               '" => "' + value + '"' + "\n";
+                               }
+                       }
+               } else {
+                               // Strings/Chars/Numbers etc.
+                       result = '[' + typeof(object) + '] ' + object;
+               }
+
+               return '<pre>' + result + '</pre>';
+       },
+       
+       /**
+        * Debug attached events of a given element (e.g. an Ext.Panel component)
+        *
+        * Note: This functionality should be used with an activated debug console like firebug!
+        *
+        * @param element object to fetch events from
+        * @return void
+        */
+       debugEvents: function(element) {
+               if (element) {
+                               // debug events of element
+                       Ext.util.Observable.capture(element, function() {
+                               console.log(
+                                       'event "' + arguments[0] + '" was fired with the following arguments: '
+                               );
+
+                               for (var i = 1; i < arguments.length; ++i) {
+                                       console.log('        [' + i + '] ', arguments[i]);
+                               }
+                       });
+               } else {
+                               // debug all events
+                       Ext.util.Observable.prototype.fireEvent =
+                               Ext.util.Observable.prototype.fireEvent.createInterceptor(function() {
+                                       console.log(arguments);
+                                       return true;
+                               });
+               }
        }
 });
 
index 6cb6a4c..c053981 100644 (file)
@@ -82,6 +82,7 @@ TYPO3.Viewport.configuration = {
                xtype: 'typo3DebugPanel',
                collapsible: true,
                collapseMode: 'mini',
+               collapsed: true,
                hideCollapseTool: true,
                animCollapse: false,
                split: true,
index 16cb5ab..99f92be 100755 (executable)
@@ -275,6 +275,7 @@ Would you like to save now in order to refresh the display?</label>
                        <label index="tabs.closeAll">Close All Tabs</label>
                        <label index="tabs.closeOther">Close Other Tabs</label>
                        <label index="tabs.close">Close Tab</label>
+                       <label index="tabs.openInBrowserWindow">Open In Browser Window</label>
                        <label index="donateWindow.title">TYPO3 donation notice</label>
                        <label index="donateWindow.message">&lt;b&gt;You have now used TYPO3 for more than three months.&lt;/b&gt; It would be great if you could donate. TYPO3 is Open Source and relies heavily on donations from its users and supporters.&lt;br/&gt; &lt;b&gt;Thank you&lt;/b&gt; for making this great Content Management System even better with your help!</label>
                        <label index="donateWindow.button_donate">Donate now</label>
index 1c1ca38..0735a1a 100755 (executable)
@@ -142,6 +142,11 @@ $GLOBALS['TYPO3_USER_SETTINGS'] = array(
                        'label' => 'LLL:EXT:setup/mod/locallang.xml:resizeTextareas_Flexible',
                        'csh' => 'resizeTextareas_Flexible',
                ),
+               'debugInWindow' => array(
+                       'type' => 'check',
+                       'label' => 'LLL:EXT:setup/mod/locallang.xml:debugInWindow',
+                       'access' => 'admin',
+               ),
                'installToolEnableButton' => array(
                        'type' => 'user',
                        'label' => 'LLL:EXT:setup/mod/locallang.xml:enableInstallTool.label',
@@ -153,7 +158,7 @@ $GLOBALS['TYPO3_USER_SETTINGS'] = array(
        'showitem' => '--div--;LLL:EXT:setup/mod/locallang.xml:personal_data,realName,email,emailMeAtLogin,password,password2,lang,
                        --div--;LLL:EXT:setup/mod/locallang.xml:opening,condensedMode,startModule,thumbnailsByDefault,helpText,edit_showFieldHelp,titleLen,
                        --div--;LLL:EXT:setup/mod/locallang.xml:editFunctionsTab,edit_RTE,edit_wideDocument,edit_docModuleUpload,enableFlashUploader,resizeTextareas,resizeTextareas_MaxHeight,resizeTextareas_Flexible,disableCMlayers,copyLevels,recursiveDelete,
-                       --div--;LLL:EXT:setup/mod/locallang.xml:adminFunctions,simulate,installToolEnableButton'
+                       --div--;LLL:EXT:setup/mod/locallang.xml:adminFunctions,simulate,debugInWindow,installToolEnableButton'
 
 );
 ?>
\ No newline at end of file
index 83cb33b..c40fd87 100755 (executable)
                        <label index="tempDataCleared">Temporary data cleared</label>
                        <label index="tempDataClearedFlashMessage">The temporary data has been cleared.</label>
                        <label index="tempDataClearedLog">Temporary data cleared</label>
+                       <label index="debugInWindow">Display debug messages in a new browser window</label>
                </languageKey>
        </data>
 </T3locallang>
index 5582176..e011d52 100644 (file)
@@ -781,7 +781,27 @@ class template {
                $this->docStyle();
 
 
-               // add jsCode - has to go to headerData as it may contain the script tags already
+                       // add jsCode for overriding the console with a debug panel connection
+               $this->pageRenderer->addJsInlineCode(
+                       'consoleOverrideWithDebugPanel',
+                       'if (typeof top.Ext === "object") {
+                               top.Ext.onReady(function() {
+                                       if (typeof console === "undefined") {
+                                               if (top && top.TYPO3 && top.TYPO3.Backend && top.TYPO3.Backend.DebugConsole) {
+                                                       console = top.TYPO3.Backend.DebugConsole;
+                                               } else {
+                                                       console = {
+                                                               log: Ext.log,
+                                                               info: Ext.log,
+                                                               warn: Ext.log,
+                                                               error: Ext.log
+                                                       }
+                                               }
+                                       }
+                               });
+                       }
+               ');
+
                $this->pageRenderer->addHeaderData($this->JScode);
 
                foreach ($this->JScodeArray as $name => $code) {
@@ -2050,6 +2070,7 @@ $str.=$this->docBodyTagBegin().
                                }
                        }
                ');
+
                        // Get the page path for the docheader
                $markerArray['PAGEPATH'] = $this->getPagePath($pageRecord);
                        // Get the page info for the docheader