Cleanup: Updated copyright notices
[Packages/TYPO3.CMS.git] / typo3 / template.php
index 1708eae..4aa9c2d 100755 (executable)
@@ -1,22 +1,22 @@
 <?php
 /***************************************************************
 *  Copyright notice
 <?php
 /***************************************************************
 *  Copyright notice
-*  
-*  (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
+*
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  All rights reserved
 *
-*  This script is part of the TYPO3 project. The TYPO3 project is 
+*  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
-* 
+*
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
-*  A copy is found in the textfile GPL.txt and important notices to the license 
+*  A copy is found in the textfile GPL.txt and important notices to the license
 *  from the author is found in LICENSE.txt distributed with these scripts.
 *
 *  from the author is found in LICENSE.txt distributed with these scripts.
 *
-* 
+*
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-/** 
+/**
  * Contains class with layout/output function for TYPO3 Backend Scripts
  *
  * $Id$
  * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
  * XHTML-trans compliant
  *
  * Contains class with layout/output function for TYPO3 Backend Scripts
  *
  * $Id$
  * Revised for TYPO3 3.6 2/2003 by Kasper Skaarhoj
  * XHTML-trans compliant
  *
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
  */
 /**
  * [CLASS/FUNCTION INDEX of SCRIPT]
  *
- *  133: function fw($str)     
+ *  145: function fw($str)
  *
  *
  *
  *
- *  157: class template 
- *  212:     function template()       
+ *  169: class template
+ *  224:     function template()
  *
  *              SECTION: EVALUATION FUNCTIONS
  *
  *              SECTION: EVALUATION FUNCTIONS
- *  279:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1)       
- *  295:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')      
- *  320:     function issueCommand($params,$rUrl='')   
- *  335:     function isCMlayers()     
- *  345:     function thisBlur()       
- *  355:     function helpStyle()      
- *  372:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))       
- *  398:     function getFileheader($title,$path,$iconfile)    
- *  413:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")    
- *  446:     function makeShortcutUrl($gvList,$setList)        
- *  468:     function formWidth($size=48,$textarea=0,$styleOverride='') 
- *  493:     function formWidthText($size=48,$styleOverride='',$wrap='') 
- *  510:     function redirectUrls($thisLocation='')   
- *  534:     function formatTime($tstamp,$type)        
- *  547:     function parseTime()      
+ *  298:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE)
+ *  315:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')
+ *  341:     function issueCommand($params,$rUrl='')
+ *  356:     function isCMlayers()
+ *  366:     function thisBlur()
+ *  376:     function helpStyle()
+ *  393:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))
+ *  419:     function getFileheader($title,$path,$iconfile)
+ *  434:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")
+ *  467:     function makeShortcutUrl($gvList,$setList)
+ *  488:     function formWidth($size=48,$textarea=0,$styleOverride='')
+ *  513:     function formWidthText($size=48,$styleOverride='',$wrap='')
+ *  530:     function redirectUrls($thisLocation='')
+ *  554:     function formatTime($tstamp,$type)
+ *  571:     function parseTime()
  *
  *              SECTION: PAGE BUILDING FUNCTIONS.
  *
  *              SECTION: PAGE BUILDING FUNCTIONS.
- *  580:     function startPage($title)        
- *  649:     function endPage()        
- *  674:     function header($text)    
- *  695:     function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)     
- *  719:     function divider($dist)   
- *  735:     function spacer($dist)    
- *  754:     function sectionHeader($label,$sH=FALSE,$addAttrib='')    
- *  771:     function sectionBegin()   
- *  792:     function sectionEnd()     
- *  812:     function middle() 
- *  821:     function endPageJS()      
- *  838:     function docBodyTagBegin()        
- *  848:     function docStyle()       
- *  889:     function insertStylesAndJS($content)      
- *  909:     function initCharset()    
- *  921:     function generator()      
+ *  604:     function startPage($title)
+ *  686:     function endPage()
+ *  720:     function header($text)
+ *  741:     function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)
+ *  765:     function divider($dist)
+ *  781:     function spacer($dist)
+ *  800:     function sectionHeader($label,$sH=FALSE,$addAttrib='')
+ *  817:     function sectionBegin()
+ *  838:     function sectionEnd()
+ *  858:     function middle()
+ *  867:     function endPageJS()
+ *  884:     function docBodyTagBegin()
+ *  894:     function docStyle()
+ *  936:     function insertStylesAndJS($content)
+ *  956:     function initCharset()
+ *  968:     function generator()
  *
  *              SECTION: OTHER ELEMENTS
  *
  *              SECTION: OTHER ELEMENTS
- *  953:     function icons($type)     
- *  982:     function t3Button($onClick,$label)        
- *  993:     function dfw($string)     
- * 1003:     function rfw($string)     
- * 1013:     function wrapInCData($string)     
- * 1030:     function wrapScriptTags($string, $linebreak=TRUE) 
- * 1067:     function table($arr)      
- * 1107:     function menuTable($arr1,$arr2=array(), $arr3=array())    
- * 1140:     function funcMenu($content,$menu) 
- * 1158:     function clearCacheMenu($id,$addSaveOptions=0)    
- * 1194:     function getContextMenuCode()     
- * 1340:     function getTabMenu($id,$elementName,$currentValue,$menuItems,$script='',$addparams='')   
+ * 1001:     function icons($type, $styleAttribValue='')
+ * 1030:     function t3Button($onClick,$label)
+ * 1041:     function dfw($string)
+ * 1051:     function rfw($string)
+ * 1061:     function wrapInCData($string)
+ * 1078:     function wrapScriptTags($string, $linebreak=TRUE)
+ * 1117:     function table($arr, $layout='')
+ * 1159:     function menuTable($arr1,$arr2=array(), $arr3=array())
+ * 1192:     function funcMenu($content,$menu)
+ * 1210:     function clearCacheMenu($id,$addSaveOptions=0)
+ * 1246:     function getContextMenuCode()
+ * 1251:     function showClickmenu(table, uid, listFr, enDisItems, backPath, addParams)
+ * 1280:     function showClickmenu_noajax(url)
+ * 1287:     function showClickmenu_ajax(t3ajax)
+ * 1472:     function getDragDropCode($table)
+ * 1483:     function cancelDragEvent(event)
+ * 1496:     function mouseMoveEvent (event)
+ * 1509:     function dragElement(id,elementID)
+ * 1528:     function dropElement(id)
+ * 1577:     function getTabMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='')
+ * 1607:     function getTabMenuRaw($menuItems)
+ * 1676:     function getDynTabMenu($menuItems,$identString,$toggle=0,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1,$fullWidth=FALSE,$defaultTabIndex=1)
+ * 1801:     function getDynTabMenuJScode()
+ * 1892:     function getVersionSelector($id,$noAction=FALSE)
  *
  *
  *
  *
- * 1452: class bigDoc extends template 
+ * 2060: class bigDoc extends template
  *
  *
  *
  *
- * 1461: class noDoc extends template 
+ * 2069: class noDoc extends template
  *
  *
  *
  *
- * 1470: class smallDoc extends template 
+ * 2078: class smallDoc extends template
  *
  *
  *
  *
- * 1479: class mediumDoc extends template 
+ * 2087: class mediumDoc extends template
  *
  *
- * TOTAL FUNCTIONS: 45
+ * TOTAL FUNCTIONS: 57
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
  * (This index is automatically created/updated by the extension "extdeveval")
  *
  */
 
 if (!defined('TYPO3_MODE'))    die("Can't include this file directly.");
 
 
 if (!defined('TYPO3_MODE'))    die("Can't include this file directly.");
 
-
+require_once(PATH_t3lib.'class.t3lib_ajax.php');
 
 
 
 
 
 
@@ -124,11 +136,11 @@ if (!defined('TYPO3_MODE'))       die("Can't include this file directly.");
 
 
 /**
 
 
 /**
- * Depreciated fontwrap function. Is just transparent now.
- * 
+ * Deprecated fontwrap function. Is just transparent now.
+ *
  * @param      string          Input string
  * @return     string          Output string (in the old days this was wrapped in <font> tags)
  * @param      string          Input string
  * @return     string          Output string (in the old days this was wrapped in <font> tags)
- * @depreciated
+ * @deprecated since TYPO3 3.6
  */
 function fw($str)      {
        return $str;
  */
 function fw($str)      {
        return $str;
@@ -137,20 +149,20 @@ function fw($str) {
 
 /**
  * TYPO3 Backend Template Class
 
 /**
  * TYPO3 Backend Template Class
- * 
+ *
  * This class contains functions for starting and ending the HTML of backend modules
  * It also contains methods for outputting sections of content.
  * Further there are functions for making icons, links, setting form-field widths etc.
  * Color scheme and stylesheet definitions are also available here.
  * Finally this file includes the language class for TYPO3's backend.
  * This class contains functions for starting and ending the HTML of backend modules
  * It also contains methods for outputting sections of content.
  * Further there are functions for making icons, links, setting form-field widths etc.
  * Color scheme and stylesheet definitions are also available here.
  * Finally this file includes the language class for TYPO3's backend.
- * 
+ *
  * After this file $LANG and $TBE_TEMPLATE are global variables / instances of their respective classes.
  * After this file $LANG and $TBE_TEMPLATE are global variables / instances of their respective classes.
- * This file is typically included right after the init.php file, 
+ * This file is typically included right after the init.php file,
  * if language and layout is needed.
  * if language and layout is needed.
- * 
+ *
  * Please refer to Inside TYPO3 for a discussion of how to use this API.
  * Please refer to Inside TYPO3 for a discussion of how to use this API.
- * 
- * @author     Kasper Skaarhoj <kasper@typo3.com>
+ *
+ * @author     Kasper Skaarhoj <kasperYYYY@typo3.com>
  * @package TYPO3
  * @subpackage core
  */
  * @package TYPO3
  * @subpackage core
  */
@@ -159,10 +171,13 @@ class template {
                // Vars you typically might want to/should set from outside after making instance of this class:
        var $backPath = '';                             // 'backPath' pointing back to the PATH_typo3
        var $form='';                                   // This can be set to the HTML-code for a formtag. Useful when you need a form to span the whole page; Inserted exactly after the body-tag.
                // Vars you typically might want to/should set from outside after making instance of this class:
        var $backPath = '';                             // 'backPath' pointing back to the PATH_typo3
        var $form='';                                   // This can be set to the HTML-code for a formtag. Useful when you need a form to span the whole page; Inserted exactly after the body-tag.
+       var $JScodeLibArray = array();          // Similar to $JScode (see below) but used as an associative array to prevent double inclusion of JS code. This is used to include certain external Javascript libraries before the inline JS code. <script>-Tags are not wrapped around automatically
        var $JScode='';                                 // Additional header code (eg. a JavaScript section) could be accommulated in this var. It will be directly outputted in the header.
        var $JScode='';                                 // Additional header code (eg. a JavaScript section) could be accommulated in this var. It will be directly outputted in the header.
-       var $JScodeArray=array();               // Similar to $JScode but for use as array with assioziative keys to prevent double inclusion of JS code. a <script> tag is automatically wrapped around.
+       var $extJsCode = '';                            // Additional header code for ExtJS. It will be included in document header and inserted in a Ext.onReady(function()
+       var $JScodeArray = array();             // Similar to $JScode but for use as array with associative keys to prevent double inclusion of JS code. a <script> tag is automatically wrapped around.
        var $postCode='';                               // Additional 'page-end' code could be accommulated in this var. It will be outputted at the end of page before </body> and some other internal page-end code.
        var $postCode='';                               // Additional 'page-end' code could be accommulated in this var. It will be outputted at the end of page before </body> and some other internal page-end code.
-       var $docType='';                                // Doc-type used in the header. Default is HTML 3.2. You can also set it to 'strict', 'xhtml_trans', or 'xhtml_frames'.
+       var $docType = '';                              // Doc-type used in the header. Default is xhtml_trans. You can also set it to 'html_3', 'xhtml_strict' or 'xhtml_frames'.
+       var $moduleTemplate = '';               // HTML template with markers for module
 
                // Other vars you can change, but less frequently used:
        var $scriptID='';                               // Script ID.
 
                // Other vars you can change, but less frequently used:
        var $scriptID='';                               // Script ID.
@@ -172,7 +187,8 @@ class template {
        var $inDocStylesArray=array();          // Like $inDocStyles but for use as array with associative keys to prevent double inclusion of css code
        var $form_rowsToStylewidth = 9.58;      // Multiplication factor for formWidth() input size (default is 48* this value).
        var $form_largeComp = 1.33;             // Compensation for large documents (used in class.t3lib_tceforms.php)
        var $inDocStylesArray=array();          // Like $inDocStyles but for use as array with associative keys to prevent double inclusion of css code
        var $form_rowsToStylewidth = 9.58;      // Multiplication factor for formWidth() input size (default is 48* this value).
        var $form_largeComp = 1.33;             // Compensation for large documents (used in class.t3lib_tceforms.php)
-       var $endJS=1;                                   // If set, then a JavaScript section will be outputted in the bottom of page which will try and update the top.busy session expiry object. 
+       var $endJS=1;                                   // If set, then a JavaScript section will be outputted in the bottom of page which will try and update the top.busy session expiry object.
+       protected $additionalStyleSheets=array();       // Links to additional style sheets
 
                // TYPO3 Colorscheme.
                // If you want to change this, please do so through a skin using the global var $TBE_STYLES
 
                // TYPO3 Colorscheme.
                // If you want to change this, please do so through a skin using the global var $TBE_STYLES
@@ -189,12 +205,12 @@ class template {
        var $backGroundImage = '';              // Background image of page (relative to PATH_typo3)
        var $inDocStyles_TBEstyle = ''; // Inline css styling set from TBE_STYLES array
 
        var $backGroundImage = '';              // Background image of page (relative to PATH_typo3)
        var $inDocStyles_TBEstyle = ''; // Inline css styling set from TBE_STYLES array
 
-               // DEV: 
+               // DEV:
        var $parseTimeFlag = 0;                 // Will output the parsetime of the scripts in milliseconds (for admin-users). Set this to false when releasing TYPO3. Only for dev.
        var $parseTimeFlag = 0;                 // Will output the parsetime of the scripts in milliseconds (for admin-users). Set this to false when releasing TYPO3. Only for dev.
-       
+
                // INTERNAL
        var $charset = 'iso-8859-1';    // Default charset. see function initCharset()
                // INTERNAL
        var $charset = 'iso-8859-1';    // Default charset. see function initCharset()
-       
+
        var $sectionFlag=0;                             // Internal: Indicates if a <div>-output section is open
        var $divClass = '';                             // (Default) Class for wrapping <DIV>-tag of page. Is set in class extensions.
 
        var $sectionFlag=0;                             // Internal: Indicates if a <div>-output section is open
        var $divClass = '';                             // (Default) Class for wrapping <DIV>-tag of page. Is set in class extensions.
 
@@ -204,20 +220,24 @@ class template {
 
 
        /**
 
 
        /**
-        * Constructor 
+        * Constructor
         * Imports relevant parts from global $TBE_STYLES (colorscheme)
         * Imports relevant parts from global $TBE_STYLES (colorscheme)
-        * 
-        * @return      void            
+        *
+        * @return      void
         */
        function template()     {
                global $TBE_STYLES;
 
                        // Setting default scriptID:
         */
        function template()     {
                global $TBE_STYLES;
 
                        // Setting default scriptID:
-               $this->scriptID = ereg_replace('^.*\/(sysext|ext)\/','ext/',substr(PATH_thisScript,strlen(PATH_site)));
+               if (($temp_M = (string) t3lib_div::_GET('M')) && $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M]) {
+                       $this->scriptID = ereg_replace('^.*\/(sysext|ext)\/', 'ext/', $GLOBALS['TBE_MODULES']['_PATHS'][$temp_M] . 'index.php');
+               } else {
+                       $this->scriptID = ereg_replace('^.*\/(sysext|ext)\/', 'ext/', substr(PATH_thisScript, strlen(PATH_site)));
+               }
                if (TYPO3_mainDir!='typo3/' && substr($this->scriptID,0,strlen(TYPO3_mainDir)) == TYPO3_mainDir)        {
                        $this->scriptID = 'typo3/'.substr($this->scriptID,strlen(TYPO3_mainDir));       // This fixes if TYPO3_mainDir has been changed so the script ids are STILL "typo3/..."
                }
                if (TYPO3_mainDir!='typo3/' && substr($this->scriptID,0,strlen(TYPO3_mainDir)) == TYPO3_mainDir)        {
                        $this->scriptID = 'typo3/'.substr($this->scriptID,strlen(TYPO3_mainDir));       // This fixes if TYPO3_mainDir has been changed so the script ids are STILL "typo3/..."
                }
-               
+
                $this->bodyTagId = ereg_replace('[^[:alnum:]-]','-',$this->scriptID);
 
                        // Individual configuration per script? If so, make a recursive merge of the arrays:
                $this->bodyTagId = ereg_replace('[^[:alnum:]-]','-',$this->scriptID);
 
                        // Individual configuration per script? If so, make a recursive merge of the arrays:
@@ -247,18 +267,18 @@ class template {
                if ($TBE_STYLES['background'])  $this->backGroundImage = $TBE_STYLES['background'];
        }
 
                if ($TBE_STYLES['background'])  $this->backGroundImage = $TBE_STYLES['background'];
        }
 
-       
-       
-       
-       
-       
-       
-       
-       
-       
-       
-       
-       
+
+
+
+
+
+
+
+
+
+
+
+
 
 
 
 
 
 
@@ -273,17 +293,20 @@ class template {
         * Makes click menu link (context sensitive menu)
         * Returns $str (possibly an <|img> tag/icon) wrapped in a link which will activate the context sensitive menu for the record ($table/$uid) or file ($table = file)
         * The link will load the top frame with the parameter "&item" which is the table,uid and listFr arguments imploded by "|": rawurlencode($table.'|'.$uid.'|'.$listFr)
         * Makes click menu link (context sensitive menu)
         * Returns $str (possibly an <|img> tag/icon) wrapped in a link which will activate the context sensitive menu for the record ($table/$uid) or file ($table = file)
         * The link will load the top frame with the parameter "&item" which is the table,uid and listFr arguments imploded by "|": rawurlencode($table.'|'.$uid.'|'.$listFr)
-        * 
+        *
         * @param       string          String to be wrapped in link, typ. image tag.
         * @param       string          Table name/File path. If the icon is for a database record, enter the tablename from $TCA. If a file then enter the absolute filepath
         * @param       integer         If icon is for database record this is the UID for the record from $table
         * @param       boolean         Tells the top frame script that the link is coming from a "list" frame which means a frame from within the backend content frame.
         * @param       string          String to be wrapped in link, typ. image tag.
         * @param       string          Table name/File path. If the icon is for a database record, enter the tablename from $TCA. If a file then enter the absolute filepath
         * @param       integer         If icon is for database record this is the UID for the record from $table
         * @param       boolean         Tells the top frame script that the link is coming from a "list" frame which means a frame from within the backend content frame.
+        * @param       string          Additional GET parameters for the link to alt_clickmenu.php
+        * @param       string          Enable / Disable click menu items. Example: "+new,view" will display ONLY these two items (and any spacers in between), "new,view" will display all BUT these two items.
+        * @param       boolean         If set, will return only the onclick JavaScript, not the whole link.
         * @return      string          The link-wrapped input string.
         */
         * @return      string          The link-wrapped input string.
         */
-       function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1)     {
-               $backPath = '&backPath='.rawurlencode($this->backPath).'|'.t3lib_div::shortMD5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
-               $onClick = 'top.loadTopMenu(\''.$this->backPath.'alt_clickmenu.php?item='.rawurlencode($table.'|'.$uid.'|'.$listFr).$backPath.'\');'.$this->thisBlur().'return false;';
-               return '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.$str.'</a>';
+       function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE)  {
+               $backPath = rawurlencode($this->backPath).'|'.t3lib_div::shortMD5($this->backPath.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']);
+               $onClick = 'showClickmenu("'.$table.'","'.$uid.'","'.$listFr.'","'.str_replace('+','%2B',$enDisItems).'","'.str_replace('&','&amp;',addcslashes($backPath,'"')).'","'.str_replace('&','&amp;',addcslashes($addParams,'"')).'");return false;';
+               return $returnOnClick ? $onClick : '<a href="#" onclick="'.htmlspecialchars($onClick).'"'.($GLOBALS['TYPO3_CONF_VARS']['BE']['useOnContextMenuHandler'] ? ' oncontextmenu="'.htmlspecialchars($onClick).'"' : '').'>'.$str.'</a>';
        }
 
        /**
        }
 
        /**
@@ -291,7 +314,7 @@ class template {
         * Returns an magnifier-glass icon which links to the frontend index.php document for viewing the page with id $id
         * $id must be a page-uid
         * If the BE_USER has access to Web>List then a link to that module is shown as well (with return-url)
         * Returns an magnifier-glass icon which links to the frontend index.php document for viewing the page with id $id
         * $id must be a page-uid
         * If the BE_USER has access to Web>List then a link to that module is shown as well (with return-url)
-        * 
+        *
         * @param       integer         The page id
         * @param       string          The current "BACK_PATH" (the back relative to the typo3/ directory)
         * @param       string          Additional parameters for the image tag(s)
         * @param       integer         The page id
         * @param       string          The current "BACK_PATH" (the back relative to the typo3/ directory)
         * @param       string          Additional parameters for the image tag(s)
@@ -317,10 +340,11 @@ class template {
        /**
         * Returns a URL with a command to TYPO3 Core Engine (tce_db.php)
         * See description of the API elsewhere.
        /**
         * Returns a URL with a command to TYPO3 Core Engine (tce_db.php)
         * See description of the API elsewhere.
-        * 
+        *
         * @param       string          $params is a set of GET params to send to tce_db.php. Example: "&cmd[tt_content][123][move]=456" or "&data[tt_content][123][hidden]=1&data[tt_content][123][title]=Hello%20World"
         * @param       string          Redirect URL if any other that t3lib_div::getIndpEnv('REQUEST_URI') is wished
         * @return      string          URL to tce_db.php + parameters (backpath is taken from $this->backPath)
         * @param       string          $params is a set of GET params to send to tce_db.php. Example: "&cmd[tt_content][123][move]=456" or "&data[tt_content][123][hidden]=1&data[tt_content][123][title]=Hello%20World"
         * @param       string          Redirect URL if any other that t3lib_div::getIndpEnv('REQUEST_URI') is wished
         * @return      string          URL to tce_db.php + parameters (backpath is taken from $this->backPath)
+        * @see t3lib_BEfunc::editOnClick()
         */
        function issueCommand($params,$rUrl='') {
                $rUrl = $rUrl ? $rUrl : t3lib_div::getIndpEnv('REQUEST_URI');
         */
        function issueCommand($params,$rUrl='') {
                $rUrl = $rUrl ? $rUrl : t3lib_div::getIndpEnv('REQUEST_URI');
@@ -334,18 +358,18 @@ class template {
        /**
         * Returns true if click-menu layers can be displayed for the current user/browser
         * Use this to test if click-menus (context sensitive menus) can and should be displayed in the backend.
        /**
         * Returns true if click-menu layers can be displayed for the current user/browser
         * Use this to test if click-menus (context sensitive menus) can and should be displayed in the backend.
-        * 
-        * @return      boolean         
+        *
+        * @return      boolean
         */
        function isCMlayers()   {
         */
        function isCMlayers()   {
-               return !$GLOBALS['BE_USER']->uc['disableCMlayers'] && $GLOBALS['CLIENT']['FORMSTYLE'] && $GLOBALS['CLIENT']['SYSTEM']!='mac';
+               return !$GLOBALS['BE_USER']->uc['disableCMlayers'] && $GLOBALS['CLIENT']['FORMSTYLE'] && !($GLOBALS['CLIENT']['SYSTEM']=='mac' && $GLOBALS['CLIENT']['BROWSER']=='Opera');
        }
 
        /**
         * Returns 'this.blur();' if the client supports CSS styles
         * Use this in links to remove the underlining after being clicked
        }
 
        /**
         * Returns 'this.blur();' if the client supports CSS styles
         * Use this in links to remove the underlining after being clicked
-        * 
-        * @return      string          
+        *
+        * @return      string
         */
        function thisBlur()     {
                return ($GLOBALS['CLIENT']['FORMSTYLE']?'this.blur();':'');
         */
        function thisBlur()     {
                return ($GLOBALS['CLIENT']['FORMSTYLE']?'this.blur();':'');
@@ -354,8 +378,8 @@ class template {
        /**
         * Returns ' style='cursor:help;'' if the client supports CSS styles
         * Use for <a>-links to help texts
        /**
         * Returns ' style='cursor:help;'' if the client supports CSS styles
         * Use for <a>-links to help texts
-        * 
-        * @return      string          
+        *
+        * @return      string
         */
        function helpStyle()    {
                return $GLOBALS['CLIENT']['FORMSTYLE'] ? ' style="cursor:help;"':'';
         */
        function helpStyle()    {
                return $GLOBALS['CLIENT']['FORMSTYLE'] ? ' style="cursor:help;"':'';
@@ -366,7 +390,7 @@ class template {
         * $table and $row must be a tablename/record from that table
         * $path will be shown as alt-text for the icon.
         * The title will be truncated to 45 chars.
         * $table and $row must be a tablename/record from that table
         * $path will be shown as alt-text for the icon.
         * The title will be truncated to 45 chars.
-        * 
+        *
         * @param       string          Table name
         * @param       array           Record row
         * @param       string          Alt text
         * @param       string          Table name
         * @param       array           Record row
         * @param       string          Alt text
@@ -388,13 +412,13 @@ class template {
 
                return '<span class="typo3-moduleHeader">'.$this->wrapClickMenuOnIcon($iconImgTag,$table,$row['uid']).
                                $viewPage.
 
                return '<span class="typo3-moduleHeader">'.$this->wrapClickMenuOnIcon($iconImgTag,$table,$row['uid']).
                                $viewPage.
-                               $tWrap[0].htmlspecialchars(t3lib_div::fixed_lgd($title,45)).$tWrap[1].'</span>';
+                               $tWrap[0].htmlspecialchars(t3lib_div::fixed_lgd_cs($title,45)).$tWrap[1].'</span>';
        }
 
        /**
         * Like ->getHeader() but for files in the File>* main module/submodules
         * Returns the file-icon with the path of the file set in the alt/title attribute. Shows the file-name after the icon.
        }
 
        /**
         * Like ->getHeader() but for files in the File>* main module/submodules
         * Returns the file-icon with the path of the file set in the alt/title attribute. Shows the file-name after the icon.
-        * 
+        *
         * @param       string          Title string, expected to be the filepath
         * @param       string          Alt text
         * @param       string          The icon file (relative to TYPO3 dir)
         * @param       string          Title string, expected to be the filepath
         * @param       string          Alt text
         * @param       string          The icon file (relative to TYPO3 dir)
@@ -402,13 +426,13 @@ class template {
         */
        function getFileheader($title,$path,$iconfile)  {
                $fileInfo = t3lib_div::split_fileref($title);
         */
        function getFileheader($title,$path,$iconfile)  {
                $fileInfo = t3lib_div::split_fileref($title);
-               $title = htmlspecialchars(t3lib_div::fixed_lgd_pre($fileInfo['path'],35)).'<b>'.htmlspecialchars($fileInfo['file']).'</b>';
+               $title = htmlspecialchars(t3lib_div::fixed_lgd_cs($fileInfo['path'],-35)).'<b>'.htmlspecialchars($fileInfo['file']).'</b>';
                return '<span class="typo3-moduleHeader"><img'.t3lib_iconWorks::skinImg($this->backPath,$iconfile,'width="18" height="16"').' title="'.htmlspecialchars($path).'" alt="" />'.$title.'</span>';
        }
 
        /**
         * Returns a linked shortcut-icon which will call the shortcut frame and set a shortcut there back to the calling page/module
                return '<span class="typo3-moduleHeader"><img'.t3lib_iconWorks::skinImg($this->backPath,$iconfile,'width="18" height="16"').' title="'.htmlspecialchars($path).'" alt="" />'.$title.'</span>';
        }
 
        /**
         * Returns a linked shortcut-icon which will call the shortcut frame and set a shortcut there back to the calling page/module
-        * 
+        *
         * @param       string          Is the list of GET variables to store (if any)
         * @param       string          Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
         * @param       string          Module name string
         * @param       string          Is the list of GET variables to store (if any)
         * @param       string          Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
         * @param       string          Module name string
@@ -419,32 +443,36 @@ class template {
                $backPath=$this->backPath;
                $storeUrl=$this->makeShortcutUrl($gvList,$setList);
                $pathInfo = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
                $backPath=$this->backPath;
                $storeUrl=$this->makeShortcutUrl($gvList,$setList);
                $pathInfo = parse_url(t3lib_div::getIndpEnv('REQUEST_URI'));
-               
+
+                       // Add the module identifier automatically if typo3/mod.php is used:
+               if (ereg('typo3/mod\.php$', $pathInfo['path']) && isset($GLOBALS['TBE_MODULES']['_PATHS'][$modName])) {
+                       $storeUrl = '&M='.$modName.$storeUrl;
+               }
+
                if (!strcmp($motherModName,'1'))        {
                        $mMN="&motherModName='+top.currentModuleLoaded+'";
                } elseif ($motherModName)       {
                        $mMN='&motherModName='.rawurlencode($motherModName);
                if (!strcmp($motherModName,'1'))        {
                        $mMN="&motherModName='+top.currentModuleLoaded+'";
                } elseif ($motherModName)       {
                        $mMN='&motherModName='.rawurlencode($motherModName);
-               } else $mMN="";
-               
-               $onClick = 'if (top.shortcutFrame && confirm('.
-                                       $GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut')).
-                                       ')){top.shortcutFrame.document.location=\''.$backPath.'alt_shortcut.php?modName='.rawurlencode($modName).
-                                       '&URL='.rawurlencode($pathInfo['path']."?".$storeUrl).
-                                       $mMN.
-                                       '\';}return false;';
-                       
-               $sIcon = '<a href="#" onclick="'.htmlspecialchars($onClick).'">
-                               <img'.t3lib_iconWorks::skinImg($backPath,'gfx/shortcut.gif','width="14" height="14"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut',1).'" alt="" /></a>';
+               } else $mMN='';
+
+               $onClick = 'top.ShortcutManager.createShortcut('
+                       .$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut')).', '
+                       .'\''.$backPath.'\', '
+                       .'\''.rawurlencode($modName).'\', '
+                       .'\''.rawurlencode($pathInfo['path']."?".$storeUrl).$mMN.'\''
+               .');return false;';
+
+               $sIcon = '<a href="#" onclick="'.htmlspecialchars($onClick).'"><img'.t3lib_iconWorks::skinImg($backPath,'gfx/shortcut.gif','width="14" height="14"').' title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:labels.makeShortcut',1).'" alt="" /></a>';
                return $sIcon;
        }
 
        /**
         * MAKE url for storing
         * Internal func
                return $sIcon;
        }
 
        /**
         * MAKE url for storing
         * Internal func
-        * 
+        *
         * @param       string          Is the list of GET variables to store (if any)
         * @param       string          Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
         * @param       string          Is the list of GET variables to store (if any)
         * @param       string          Is the list of SET[] variables to store (if any) - SET[] variables a stored in $GLOBALS["SOBE"]->MOD_SETTINGS for backend modules
-        * @return      string          
+        * @return      string
         * @access private
         * @see makeShortcutIcon()
         */
         * @access private
         * @see makeShortcutIcon()
         */
@@ -452,7 +480,7 @@ class template {
                $GET = t3lib_div::_GET();
                $storeArray = array_merge(
                        t3lib_div::compileSelectedGetVarsFromArray($gvList,$GET),
                $GET = t3lib_div::_GET();
                $storeArray = array_merge(
                        t3lib_div::compileSelectedGetVarsFromArray($gvList,$GET),
-                       array('SET'=>t3lib_div::compileSelectedGetVarsFromArray($setList,$GLOBALS['SOBE']->MOD_SETTINGS))
+                       array('SET'=>t3lib_div::compileSelectedGetVarsFromArray($setList, (array)$GLOBALS['SOBE']->MOD_SETTINGS))
                );
                $storeUrl = t3lib_div::implodeArrayForUrl('',$storeArray);
                return $storeUrl;
                );
                $storeUrl = t3lib_div::implodeArrayForUrl('',$storeArray);
                return $storeUrl;
@@ -462,9 +490,9 @@ class template {
         * Returns <input> attributes to set the width of an text-type input field.
         * For client browsers with no CSS support the cols/size attribute is returned.
         * For CSS compliant browsers (recommended) a ' style="width: ...px;"' is returned.
         * Returns <input> attributes to set the width of an text-type input field.
         * For client browsers with no CSS support the cols/size attribute is returned.
         * For CSS compliant browsers (recommended) a ' style="width: ...px;"' is returned.
-        * 
+        *
         * @param       integer         A relative number which multiplied with approx. 10 will lead to the width in pixels
         * @param       integer         A relative number which multiplied with approx. 10 will lead to the width in pixels
-        * @param       boolean         A flag you can set for textareas - DEPRECIATED, use ->formWidthText() for textareas!!!
+        * @param       boolean         A flag you can set for textareas - DEPRECATED, use ->formWidthText() for textareas!!!
         * @param       string          A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
         * @return      string          Tag attributes for an <input> tag (regarding width)
         * @see formWidthText()
         * @param       string          A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
         * @return      string          Tag attributes for an <input> tag (regarding width)
         * @see formWidthText()
@@ -487,7 +515,7 @@ class template {
         *              <textarea rows="10" wrap="off" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","off").'>
         *   or
         *              <textarea rows="10" wrap="virtual" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","virtual").'>
         *              <textarea rows="10" wrap="off" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","off").'>
         *   or
         *              <textarea rows="10" wrap="virtual" '.$GLOBALS["TBE_TEMPLATE"]->formWidthText(48,"","virtual").'>
-        * 
+        *
         * @param       integer         A relative number which multiplied with approx. 10 will lead to the width in pixels
         * @param       string          A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
         * @param       string          Pass on the wrap-attribute value you use in your <textarea>! This will be used to make sure that some browsers will detect wrapping alright.
         * @param       integer         A relative number which multiplied with approx. 10 will lead to the width in pixels
         * @param       string          A string which will be returned as attribute-value for style="" instead of the calculated width (if CSS is enabled)
         * @param       string          Pass on the wrap-attribute value you use in your <textarea>! This will be used to make sure that some browsers will detect wrapping alright.
@@ -506,9 +534,9 @@ class template {
        /**
         * Returns JavaScript variables setting the returnUrl and thisScript location for use by JavaScript on the page.
         * Used in fx. db_list.php (Web>List)
        /**
         * Returns JavaScript variables setting the returnUrl and thisScript location for use by JavaScript on the page.
         * Used in fx. db_list.php (Web>List)
-        * 
+        *
         * @param       string          URL to "this location" / current script
         * @param       string          URL to "this location" / current script
-        * @return      string          
+        * @return      string
         * @see typo3/db_list.php
         */
        function redirectUrls($thisLocation='') {
         * @see typo3/db_list.php
         */
        function redirectUrls($thisLocation='') {
@@ -519,7 +547,7 @@ class template {
                        'cmd' => '',
                        'popViewId'=>''
                ));
                        'cmd' => '',
                        'popViewId'=>''
                ));
-               
+
                $out ="
        var T3_RETURN_URL = '".str_replace('%20','',rawurlencode(t3lib_div::_GP('returnUrl')))."';
        var T3_THIS_LOCATION = '".str_replace('%20','',rawurlencode($thisLocation))."';
                $out ="
        var T3_RETURN_URL = '".str_replace('%20','',rawurlencode(t3lib_div::_GP('returnUrl')))."';
        var T3_THIS_LOCATION = '".str_replace('%20','',rawurlencode($thisLocation))."';
@@ -530,23 +558,27 @@ class template {
        /**
         * Returns a formatted string of $tstamp
         * Uses $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] and $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] to format date and time
        /**
         * Returns a formatted string of $tstamp
         * Uses $GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'] and $GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'] to format date and time
-        * 
+        *
         * @param       integer         UNIX timestamp, seconds since 1970
         * @param       integer         How much data to show: $type = 1: hhmm, $type = 10:     ddmmmyy
         * @return      string          Formatted timestamp
         */
        function formatTime($tstamp,$type)      {
         * @param       integer         UNIX timestamp, seconds since 1970
         * @param       integer         How much data to show: $type = 1: hhmm, $type = 10:     ddmmmyy
         * @return      string          Formatted timestamp
         */
        function formatTime($tstamp,$type)      {
+               $dateStr = '';
                switch($type)   {
                switch($type)   {
-                       case 1: return date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],$tstamp); break; 
-                       case 10: return date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],$tstamp); break;              
+                       case 1: $dateStr = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['hhmm'],$tstamp);
+                       break;
+                       case 10: $dateStr = date($GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'],$tstamp);
+                       break;
                }
                }
+               return $dateStr;
        }
 
        /**
         * Returns script parsetime IF ->parseTimeFlag is set and user is "admin"
         * Automatically outputted in page end
        }
 
        /**
         * Returns script parsetime IF ->parseTimeFlag is set and user is "admin"
         * Automatically outputted in page end
-        * 
-        * @return      string          
+        *
+        * @return      string
         */
        function parseTime()    {
                if ($this->parseTimeFlag && $GLOBALS['BE_USER']->isAdmin()) {
         */
        function parseTime()    {
                if ($this->parseTimeFlag && $GLOBALS['BE_USER']->isAdmin()) {
@@ -558,8 +590,8 @@ class template {
 
 
 
 
 
 
-       
-       
+
+
 
 
 
 
 
 
@@ -576,51 +608,71 @@ class template {
        /**
         * Returns page start
         * This includes the proper header with charset, title, meta tag and beginning body-tag.
        /**
         * Returns page start
         * This includes the proper header with charset, title, meta tag and beginning body-tag.
-        * 
+        *
         * @param       string          HTML Page title for the header
         * @return      string          Returns the whole header section of a HTML-document based on settings in internal variables (like styles, javascript code, charset, generator and docType)
         * @see endPage()
         */
        function startPage($title)      {
         * @param       string          HTML Page title for the header
         * @return      string          Returns the whole header section of a HTML-document based on settings in internal variables (like styles, javascript code, charset, generator and docType)
         * @see endPage()
         */
        function startPage($title)      {
+                       // hook pre start page
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'])) {
+                       $preStartPageHook =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/template.php']['preStartPageHook'];
+                       if (is_array($preStartPageHook)) {
+                               $hookParameters = array(
+                                       'title' => &$title,
+                               );
+                               foreach ($preStartPageHook as $hookFunction)    {
+                                       t3lib_div::callUserFunction($hookFunction, $hookParameters, $this);
+                               }
+                       }
+               }
+
                        // Get META tag containing the currently selected charset for backend output. The function sets $this->charSet.
                $charSet = $this->initCharset();
                $generator = $this->generator();
                        // Get META tag containing the currently selected charset for backend output. The function sets $this->charSet.
                $charSet = $this->initCharset();
                $generator = $this->generator();
-               
+
                        // For debugging: If this outputs "QuirksMode"/"BackCompat" (IE) the browser runs in quirks-mode. Otherwise the value is "CSS1Compat"
 #              $this->JScodeArray[]='alert(document.compatMode);';
                        // For debugging: If this outputs "QuirksMode"/"BackCompat" (IE) the browser runs in quirks-mode. Otherwise the value is "CSS1Compat"
 #              $this->JScodeArray[]='alert(document.compatMode);';
-               
+
                        // Send HTTP header for selected charset. Added by Robert Lemke 23.10.2003
                header ('Content-Type:text/html;charset='.$this->charset);
 
                switch($this->docType)  {
                        // Send HTTP header for selected charset. Added by Robert Lemke 23.10.2003
                header ('Content-Type:text/html;charset='.$this->charset);
 
                switch($this->docType)  {
+                       case 'html_3':
+                               $headerStart = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">';
+                               break;
                        case 'xhtml_strict':
                        case 'xhtml_strict':
-                               $headerStart= '<!DOCTYPE html 
-       PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
+                               $headerStart = '<!DOCTYPE html
+       PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 <?xml-stylesheet href="#internalStyle" type="text/css"?>
 ';
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 <?xml-stylesheet href="#internalStyle" type="text/css"?>
 ';
-                       break;
-                       case 'xhtml_trans':
-                               $headerStart= '<!DOCTYPE html 
-     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<?xml version="1.0" encoding="'.$this->charset.'"?>
-<?xml-stylesheet href="#internalStyle" type="text/css"?>
-';
-                       break;
+                               break;
                        case 'xhtml_frames':
                        case 'xhtml_frames':
-                               $headerStart= '<!DOCTYPE html 
+                               $headerStart = '<!DOCTYPE html
      PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 ';
      PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
 <?xml version="1.0" encoding="'.$this->charset.'"?>
 ';
-                       break;
+                               break;
+                       // The fallthrough is intended as XHTML 1.0 transitional is the default for the BE.
+                       case 'xhtml_trans':
                        default:
                        default:
-                               $headerStart='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">';
-                       break;
+                               $headerStart = '<!DOCTYPE html
+     PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<?xml version="1.0" encoding="'.$this->charset.'"?>
+<?xml-stylesheet href="#internalStyle" type="text/css"?>
+';
                }
                }
-               
+
+               // This loads the tabulator-in-textarea feature. It automatically modifies
+               // every textarea which is found.
+               if (!$GLOBALS['BE_USER']->uc['disableTabInTextarea']) {
+                       $this->loadJavascriptLib('tab.js');
+               }
+
                        // Construct page header.
                $str = $headerStart.'
 <html>
                        // Construct page header.
                $str = $headerStart.'
 <html>
@@ -630,29 +682,33 @@ class template {
        '.$generator.'
        <title>'.htmlspecialchars($title).'</title>
        '.$this->docStyle().'
        '.$generator.'
        <title>'.htmlspecialchars($title).'</title>
        '.$this->docStyle().'
+       '.implode("\n", $this->JScodeLibArray).'
        '.$this->JScode.'
        '.$this->JScode.'
-       '.$this->wrapScriptTags(implode("\n", $this->JScodeArray)).'
+       '.$this->wrapScriptTags(implode("\n", $this->JScodeArray)).
+       ($this->extJsCode ? $this->wrapScriptTags('Ext.onReady(function() {' . chr(10) . $this->extJsCode . chr(10) . '});') : '') .
+       '
        <!--###POSTJSMARKER###-->
 </head>
 ';
        <!--###POSTJSMARKER###-->
 </head>
 ';
-               $this->JScode='';
-               $this->JScodeArray=array();
+               $this->JScodeLibArray = array();
+               $this->JScode = $this->extJsCode = '';
+               $this->JScodeArray = array();
 
                if ($this->docType=='xhtml_frames')     {
                        return $str;
 
                if ($this->docType=='xhtml_frames')     {
                        return $str;
-               } else 
+               } else
 $str.=$this->docBodyTagBegin().
 ($this->divClass?'
 
 <!-- Wrapping DIV-section for whole page BEGIN -->
 <div class="'.$this->divClass.'">
 $str.=$this->docBodyTagBegin().
 ($this->divClass?'
 
 <!-- Wrapping DIV-section for whole page BEGIN -->
 <div class="'.$this->divClass.'">
-':'').trim($this->form);       
+':'').trim($this->form);
                return $str;
        }
 
        /**
         * Returns page end; This includes finishing form, div, body and html tags.
                return $str;
        }
 
        /**
         * Returns page end; This includes finishing form, div, body and html tags.
-        * 
+        *
         * @return      string          The HTML end of a page
         * @see startPage()
         */
         * @return      string          The HTML end of a page
         * @see startPage()
         */
@@ -660,24 +716,33 @@ $str.=$this->docBodyTagBegin().
                $str = $this->sectionEnd().
                                $this->postCode.
                                $this->endPageJS().
                $str = $this->sectionEnd().
                                $this->postCode.
                                $this->endPageJS().
-                               t3lib_BEfunc::getSetUpdateSignal().
+                               $this->wrapScriptTags(t3lib_BEfunc::getUpdateSignalCode()).
                                $this->parseTime().
                                ($this->form?'
                                $this->parseTime().
                                ($this->form?'
-</form>':'').
-                               ($this->divClass?'
+</form>':'');
+
+               if ($this->docType!='xhtml_frames') {
+
+                       $str .= ($this->divClass?'
 
 <!-- Wrapping DIV-section for whole page END -->
 
 <!-- Wrapping DIV-section for whole page END -->
-</div>':'').
-                               '
-</body>
-</html>        ';
+</div>':'').'
+</body>        ';
+
+               }
+
+               $str .= '</html>';
+
+                       // Logging: Can't find better place to put it:
+               if (TYPO3_DLOG) t3lib_div::devLog('END of BACKEND session', 'template', 0, array('_FLUSH' => true));
+
                return $str;
        }
 
        /**
         * Returns the header-bar in the top of most backend modules
         * Closes section if open.
                return $str;
        }
 
        /**
         * Returns the header-bar in the top of most backend modules
         * Closes section if open.
-        * 
+        *
         * @param       string          The text string for the header
         * @return      string          HTML content
         */
         * @param       string          The text string for the header
         * @return      string          HTML content
         */
@@ -689,10 +754,10 @@ $str.=$this->docBodyTagBegin().
 ';
                return $this->sectionEnd().$str;
        }
 ';
                return $this->sectionEnd().$str;
        }
-       
+
        /**
         * Begins an output section and sets header and content
        /**
         * Begins an output section and sets header and content
-        * 
+        *
         * @param       string          The header
         * @param       string          The HTML-content
         * @param       boolean         A flag that will prevent the header from being converted to uppercase
         * @param       string          The header
         * @param       string          The HTML-content
         * @param       boolean         A flag that will prevent the header from being converted to uppercase
@@ -704,7 +769,7 @@ $str.=$this->docBodyTagBegin().
         */
        function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)   {
                $str='';
         */
        function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)   {
                $str='';
-               
+
                        // Setting header
                if ($label)     {
                        if (!$allowHTMLinHeader)        $label = htmlspecialchars($label);
                        // Setting header
                if ($label)     {
                        if (!$allowHTMLinHeader)        $label = htmlspecialchars($label);
@@ -715,14 +780,14 @@ $str.=$this->docBodyTagBegin().
 
        <!-- Section content -->
 '.$text;
 
        <!-- Section content -->
 '.$text;
-               
+
                return $this->sectionBegin().$str;
        }
 
        /**
         * Inserts a divider image
         * Ends a section (if open) before inserting the image
                return $this->sectionBegin().$str;
        }
 
        /**
         * Inserts a divider image
         * Ends a section (if open) before inserting the image
-        * 
+        *
         * @param       integer         The margin-top/-bottom of the <hr> ruler.
         * @return      string          HTML content
         */
         * @param       integer         The margin-top/-bottom of the <hr> ruler.
         * @return      string          HTML content
         */
@@ -738,8 +803,8 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * Returns a blank <div>-section with a height
 
        /**
         * Returns a blank <div>-section with a height
-        * 
-        * @param       integer         Padding-top for the div-section (should be margin-top but konquorer (3.1) don't like it :-(
+        *
+        * @param       integer         Padding-top for the div-section (should be margin-top but konqueror (3.1) doesn't like it :-(
         * @return      string          HTML content
         */
        function spacer($dist)  {
         * @return      string          HTML content
         */
        function spacer($dist)  {
@@ -755,7 +820,7 @@ $str.=$this->docBodyTagBegin().
        /**
         * Make a section header.
         * Begins a section if not already open.
        /**
         * Make a section header.
         * Begins a section if not already open.
-        * 
+        *
         * @param       string          The label between the <h3> or <h4> tags. (Allows HTML)
         * @param       boolean         If set, <h3> is used, otherwise <h4>
         * @param       string          Additional attributes to h-tag, eg. ' class=""'
         * @param       string          The label between the <h3> or <h4> tags. (Allows HTML)
         * @param       boolean         If set, <h3> is used, otherwise <h4>
         * @param       string          Additional attributes to h-tag, eg. ' class=""'
@@ -775,7 +840,7 @@ $str.=$this->docBodyTagBegin().
         * Begins an output section.
         * Returns the <div>-begin tag AND sets the ->sectionFlag true (if the ->sectionFlag is not already set!)
         * You can call this function even if a section is already begun since the function will only return something if the sectionFlag is not already set!
         * Begins an output section.
         * Returns the <div>-begin tag AND sets the ->sectionFlag true (if the ->sectionFlag is not already set!)
         * You can call this function even if a section is already begun since the function will only return something if the sectionFlag is not already set!
-        * 
+        *
         * @return      string          HTML content
         */
        function sectionBegin() {
         * @return      string          HTML content
         */
        function sectionBegin() {
@@ -784,19 +849,19 @@ $str.=$this->docBodyTagBegin().
                        $str='
 
        <!-- ***********************
                        $str='
 
        <!-- ***********************
-             Begin output section. 
+             Begin output section.
             *********************** -->
        <div>
 ';
                        return $str;
                } else return '';
        }
             *********************** -->
        <div>
 ';
                        return $str;
                } else return '';
        }
-       
+
        /**
         * Ends and output section
         * Returns the </div>-end tag AND clears the ->sectionFlag (but does so only IF the sectionFlag is set - that is a section is 'open')
         * See sectionBegin() also.
        /**
         * Ends and output section
         * Returns the </div>-end tag AND clears the ->sectionFlag (but does so only IF the sectionFlag is set - that is a section is 'open')
         * See sectionBegin() also.
-        * 
+        *
         * @return      string          HTML content
         */
        function sectionEnd()   {
         * @return      string          HTML content
         */
        function sectionEnd()   {
@@ -805,19 +870,19 @@ $str.=$this->docBodyTagBegin().
                        return '
        </div>
        <!-- *********************
                        return '
        </div>
        <!-- *********************
-             End output section. 
+             End output section.
             ********************* -->
 ';
                } else return '';
        }
             ********************* -->
 ';
                } else return '';
        }
-       
+
        /**
         * Originally it printed a kind of divider.
        /**
         * Originally it printed a kind of divider.
-        * Depreciated. Just remove function calls to it or call the divider() function instead.
-        * 
-        * @return      void            
+        * Deprecated. Just remove function calls to it or call the divider() function instead.
+        *
+        * @return      void
         * @internal
         * @internal
-        * @depreciated
+        * @deprecated since TYPO3 3.6
         */
        function middle()       {
        }
         */
        function middle()       {
        }
@@ -825,7 +890,7 @@ $str.=$this->docBodyTagBegin().
        /**
         * If a form-tag is defined in ->form then and end-tag for that <form> element is outputted
         * Further a JavaScript section is outputted which will update the top.busy session-expiry object (unless $this->endJS is set to false)
        /**
         * If a form-tag is defined in ->form then and end-tag for that <form> element is outputted
         * Further a JavaScript section is outputted which will update the top.busy session-expiry object (unless $this->endJS is set to false)
-        * 
+        *
         * @return      string          HTML content (<script> tag section)
         */
        function endPageJS()    {
         * @return      string          HTML content (<script> tag section)
         */
        function endPageJS()    {
@@ -842,30 +907,30 @@ $str.=$this->docBodyTagBegin().
        /**
         * Creates the bodyTag.
         * You can add to the bodyTag by $this->bodyTagAdditions
        /**
         * Creates the bodyTag.
         * You can add to the bodyTag by $this->bodyTagAdditions
-        * 
+        *
         * @return      string          HTML body tag
         */
        function docBodyTagBegin()      {
         * @return      string          HTML body tag
         */
        function docBodyTagBegin()      {
-               $bodyContent = 'body '.trim($this->bodyTagAdditions.($this->bodyTagId ? ' id="'.$this->bodyTagId.'"' : ''));
+               $bodyContent = 'body onclick="if (top.menuReset) top.menuReset();" '.trim($this->bodyTagAdditions.($this->bodyTagId ? ' id="'.$this->bodyTagId.'"' : ''));
                return '<'.trim($bodyContent).'>';
        }
 
        /**
         * Outputting document style
                return '<'.trim($bodyContent).'>';
        }
 
        /**
         * Outputting document style
-        * 
+        *
         * @return      string          HTML style section/link tags
         */
        function docStyle()     {
         * @return      string          HTML style section/link tags
         */
        function docStyle()     {
-       
+
                        // Request background image:
                if ($this->backGroundImage)     {
                        $this->inDocStylesArray[]=' BODY { background-image: url('.$this->backPath.$this->backGroundImage.'); }';
                }
 
                        // Request background image:
                if ($this->backGroundImage)     {
                        $this->inDocStylesArray[]=' BODY { background-image: url('.$this->backPath.$this->backGroundImage.'); }';
                }
 
-                       // Add inDoc styles variables as well:          
+                       // Add inDoc styles variables as well:
                $this->inDocStylesArray[] = $this->inDocStyles;
                $this->inDocStylesArray[] = $this->inDocStyles_TBEstyle;
                $this->inDocStylesArray[] = $this->inDocStyles;
                $this->inDocStylesArray[] = $this->inDocStyles_TBEstyle;
-               
+
                        // Implode it all:
                $inDocStyles = implode('
                                        ',$this->inDocStylesArray);
                        // Implode it all:
                $inDocStyles = implode('
                                        ',$this->inDocStylesArray);
@@ -874,13 +939,14 @@ $str.=$this->docBodyTagBegin().
                $style=trim('
                        '.($this->styleSheetFile?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile.'" />':'').'
                        '.($this->styleSheetFile2?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile2.'" />':'').'
                $style=trim('
                        '.($this->styleSheetFile?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile.'" />':'').'
                        '.($this->styleSheetFile2?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile2.'" />':'').'
-                       '.(trim($inDocStyles) ? '
                        <style type="text/css" id="internalStyle">
                                /*<![CDATA[*/
                                        '.trim($inDocStyles).'
                        <style type="text/css" id="internalStyle">
                                /*<![CDATA[*/
                                        '.trim($inDocStyles).'
+                                       /*###POSTCSSMARKER###*/
                                /*]]>*/
                                /*]]>*/
-                       </style>' : '').'
-                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'')
+                       </style>
+                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'').'
+                       '.implode("\n", $this->additionalStyleSheets)
                )
                ;
                $this->inDocStyles='';
                )
                ;
                $this->inDocStyles='';
@@ -891,8 +957,24 @@ $str.=$this->docBodyTagBegin().
        }
 
        /**
        }
 
        /**
+        * Insert additional style sheet link
+        *
+        * @param       string          $key: some key identifying the style sheet
+        * @param       string          $href: uri to the style sheet file
+        * @param       string          $title: value for the title attribute of the link element
+        * @return      string          $relation: value for the rel attribute of the link element
+        * @return      void
+        */
+       function addStyleSheet($key, $href, $title='', $relation='stylesheet') {
+               if (!isset($this->additionalStyleSheets[$key])) {
+                       $this->additionalStyleSheets[$key] = '<link rel="' . $relation . '" type="text/css" href="' . $href . '"' . ($title ? (' title="' . $title . '"') : '') . ' />';
+               }
+        }
+
+       /**
         * Insert post rendering document style into already rendered content
         * Insert post rendering document style into already rendered content
-        * 
+        * This is needed for extobjbase
+        *
         * @param       string          style-content to insert.
         * @return      string          content with inserted styles
         */
         * @param       string          style-content to insert.
         * @return      string          content with inserted styles
         */
@@ -913,7 +995,7 @@ $str.=$this->docBodyTagBegin().
         * Initialize the charset.
         * Sets the internal $this->charset variable to the charset defined in $GLOBALS["LANG"] (or the default as set in this class)
         * Returns the meta-tag for the document header
         * Initialize the charset.
         * Sets the internal $this->charset variable to the charset defined in $GLOBALS["LANG"] (or the default as set in this class)
         * Returns the meta-tag for the document header
-        * 
+        *
         * @return      string          <meta> tag with charset from $this->charset or $GLOBALS['LANG']->charSet
         */
        function initCharset()  {
         * @return      string          <meta> tag with charset from $this->charset or $GLOBALS['LANG']->charSet
         */
        function initCharset()  {
@@ -925,12 +1007,12 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * Returns generator meta tag
 
        /**
         * Returns generator meta tag
-        * 
-        * @return      string          <meta> tag with name "GENERATOR"
+        *
+        * @return      string          <meta> tag with name "generator"
         */
        function generator()    {
         */
        function generator()    {
-               $str = 'TYPO3 '.$GLOBALS['TYPO_VERSION'].', http://typo3.com, &#169; Kasper Sk&#229;rh&#248;j 1998-2004, extensions are copyright of their respective owners.';
-               return '<meta name="GENERATOR" content="'.$str .'" />';
+               $str = 'TYPO3 '.TYPO3_branch.', http://typo3.com, &#169; Kasper Sk&#229;rh&#248;j 1998-2008, extensions are copyright of their respective owners.';
+               return '<meta name="generator" content="'.$str .'" />';
        }
 
 
        }
 
 
@@ -950,17 +1032,18 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * Returns an image-tag with an 18x16 icon of the following types:
 
        /**
         * Returns an image-tag with an 18x16 icon of the following types:
-        * 
+        *
         * $type:
         * -1:  OK icon (Check-mark)
         * 1:   Notice (Speach-bubble)
         * 2:   Warning (Yellow triangle)
         * 3:   Fatal error (Red stop sign)
         * $type:
         * -1:  OK icon (Check-mark)
         * 1:   Notice (Speach-bubble)
         * 2:   Warning (Yellow triangle)
         * 3:   Fatal error (Red stop sign)
-        * 
+        *
         * @param       integer         See description
         * @param       integer         See description
+        * @param       string          Value for style attribute
         * @return      string          HTML image tag (if applicable)
         */
         * @return      string          HTML image tag (if applicable)
         */
-       function icons($type)   {
+       function icons($type, $styleAttribValue='')     {
                switch($type)   {
                        case '3':
                                $icon = 'gfx/icon_fatalerror.gif';
                switch($type)   {
                        case '3':
                                $icon = 'gfx/icon_fatalerror.gif';
@@ -978,13 +1061,13 @@ $str.=$this->docBodyTagBegin().
                        break;
                }
                if ($icon)      {
                        break;
                }
                if ($icon)      {
-                       return '<img'.t3lib_iconWorks::skinImg($this->backPath,$icon,'width="18" height="16"').' class="absmiddle" alt="" />';
-               } 
+                       return '<img'.t3lib_iconWorks::skinImg($this->backPath,$icon,'width="18" height="16"').' class="absmiddle"'.($styleAttribValue ? ' style="'.htmlspecialchars($styleAttribValue).'"' : '').' alt="" />';
+               }
        }
 
        /**
         * Returns an <input> button with the $onClick action and $label
        }
 
        /**
         * Returns an <input> button with the $onClick action and $label
-        * 
+        *
         * @param       string          The value of the onclick attribute of the input tag (submit type)
         * @param       string          The label for the button (which will be htmlspecialchar'ed)
         * @return      string          A <input> tag of the type "submit"
         * @param       string          The value of the onclick attribute of the input tag (submit type)
         * @param       string          The label for the button (which will be htmlspecialchar'ed)
         * @return      string          A <input> tag of the type "submit"
@@ -996,7 +1079,7 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * dimmed-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be gray/dimmed
 
        /**
         * dimmed-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be gray/dimmed
-        * 
+        *
         * @param       string          Input string
         * @return      string          Output string
         */
         * @param       string          Input string
         * @return      string          Output string
         */
@@ -1006,7 +1089,7 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * red-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be red
 
        /**
         * red-fontwrap. Returns the string wrapped in a <span>-tag defining the color to be red
-        * 
+        *
         * @param       string          Input string
         * @return      string          Output string
         */
         * @param       string          Input string
         * @return      string          Output string
         */
@@ -1016,7 +1099,7 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * Returns string wrapped in CDATA "tags" for XML / XHTML (wrap content of <script> and <style> sections in those!)
 
        /**
         * Returns string wrapped in CDATA "tags" for XML / XHTML (wrap content of <script> and <style> sections in those!)
-        * 
+        *
         * @param       string          Input string
         * @return      string          Output string
         */
         * @param       string          Input string
         * @return      string          Output string
         */
@@ -1027,12 +1110,12 @@ $str.=$this->docBodyTagBegin().
 
                return $string;
        }
 
                return $string;
        }
-       
+
        /**
         * Wraps the input string in script tags.
         * Automatic re-identing of the JS code is done by using the first line as ident reference.
         * This is nice for identing JS code with PHP code on the same level.
        /**
         * Wraps the input string in script tags.
         * Automatic re-identing of the JS code is done by using the first line as ident reference.
         * This is nice for identing JS code with PHP code on the same level.
-        * 
+        *
         * @param       string          Input string
         * @param       boolean         Wrap script element in linebreaks? Default is TRUE.
         * @return      string          Output string
         * @param       string          Input string
         * @param       boolean         Wrap script element in linebreaks? Default is TRUE.
         * @return      string          Output string
@@ -1045,6 +1128,7 @@ $str.=$this->docBodyTagBegin().
                                // remove nl from the beginning
                        $string = preg_replace ('/^\n+/', '', $string);
                                // re-ident to one tab using the first line as reference
                                // remove nl from the beginning
                        $string = preg_replace ('/^\n+/', '', $string);
                                // re-ident to one tab using the first line as reference
+                       $match = array();
                        if(preg_match('/^(\t+)/',$string,$match)) {
                                $string = str_replace($match[1],"\t", $string);
                        }
                        if(preg_match('/^(\t+)/',$string,$match)) {
                                $string = str_replace($match[1],"\t", $string);
                        }
@@ -1057,58 +1141,63 @@ $str.=$this->docBodyTagBegin().
                return trim($string);
        }
 
                return trim($string);
        }
 
-               // These vars defines the layout for the table produced by the table() function. 
+               // These vars defines the layout for the table produced by the table() function.
                // You can override these values from outside if you like.
                // You can override these values from outside if you like.
-       var $tableLayout = Array (
-               'defRow' => Array (
-                       'defCol' => Array('<td valign="top">','</td>')
+       var $tableLayout = array(
+               'defRow' => array(
+                       'defCol' => array('<td valign="top">','</td>')
                )
        );
        var $table_TR = '<tr>';
        var $table_TABLE = '<table border="0" cellspacing="0" cellpadding="0" id="typo3-tmpltable">';
 
        /**
                )
        );
        var $table_TR = '<tr>';
        var $table_TABLE = '<table border="0" cellspacing="0" cellpadding="0" id="typo3-tmpltable">';
 
        /**
-        * Returns a table based on the input $arr
-        * 
+        * Returns a table based on the input $data
+        *
         * @param       array           Multidim array with first levels = rows, second levels = cells
         * @param       array           Multidim array with first levels = rows, second levels = cells
+        * @param       array           If set, then this provides an alternative layout array instead of $this->tableLayout
         * @return      string          The HTML table.
         * @internal
         */
         * @return      string          The HTML table.
         * @internal
         */
-       function table($arr)    {
-               if (is_array($arr))     {
-                       reset($arr);
-                       $code='';
-                       $rc=0;
-                       while(list(,$val)=each($arr))   {
-                               if ($rc % 2) {
-                                       $layout = is_array($this->tableLayout['defRowOdd']) ? $this->tableLayout['defRowOdd'] : $this->tableLayout['defRow'];
+       function table($data, $layout = '') {
+               $result = '';
+               if (is_array($data)) {
+                       $tableLayout = (is_array($layout) ? $layout : $this->tableLayout);
+
+                       $rowCount = 0;
+                       foreach ($data as $tableRow) {
+                               if ($rowCount % 2) {
+                                       $layout = is_array($tableLayout['defRowOdd']) ? $tableLayout['defRowOdd'] : $tableLayout['defRow'];
                                } else {
                                } else {
-                                       $layout = is_array($this->tableLayout['defRowEven']) ? $this->tableLayout['defRowEven'] : $this->tableLayout['defRow'];
+                                       $layout = is_array($tableLayout['defRowEven']) ? $tableLayout['defRowEven'] : $tableLayout['defRow'];
                                }
                                }
-                               $layout = is_array($this->tableLayout[$rc]) ? $this->tableLayout[$rc] : $layout;
-                               $code_td='';
-                               if (is_array($val))     {
-                                       $cc=0;
-                                       while(list(,$content)=each($val))       {
-                                               $wrap= is_array($layout[$cc]) ? $layout[$cc] : $layout['defCol'];
-                                               $code_td.=$wrap[0].$content.$wrap[1];
-                                               $cc++;
+                               $rowLayout = is_array($tableLayout[$rowCount]) ? $tableLayout[$rowCount] : $layout;
+                               $rowResult = '';
+                               if (is_array($tableRow)) {
+                                       $cellCount = 0;
+                                       foreach ($tableRow as $tableCell) {
+                                               $cellWrap = (is_array($layout[$cellCount])    ? $layout[$cellCount]    : $layout['defCol']);
+                                               $cellWrap = (is_array($rowLayout['defCol'])   ? $rowLayout['defCol']   : $cellWrap);
+                                               $cellWrap = (is_array($rowLayout[$cellCount]) ? $rowLayout[$cellCount] : $cellWrap);
+                                               $rowResult .= $cellWrap[0] . $tableCell . $cellWrap[1];
+                                               $cellCount++;
                                        }
                                }
                                        }
                                }
-                               $trWrap = is_array($layout['tr']) ? $layout['tr'] : array($this->table_TR, '</tr>');
-                               $code.=$trWrap[0].$code_td.$trWrap[1];
-                               $rc++;
+                               $rowWrap = (is_array($layout['tr'])    ? $layout['tr']    : array($this->table_TR, '</tr>'));
+                               $rowWrap = (is_array($rowLayout['tr']) ? $rowLayout['tr'] : $rowWrap);
+                               $result .= $rowWrap[0] . $rowResult . $rowWrap[1];
+                               $rowCount++;
                        }
                        }
-                       $tableWrap = is_array($this->tableLayout['table']) ? $this->tableLayout['table'] : array($this->table_TABLE, '</table>');
-                       $code=$tableWrap[0].$code.$tableWrap[1];
+                       $tableWrap = is_array($tableLayout['table']) ? $tableLayout['table'] : array($this->table_TABLE, '</table>');
+                       $result = $tableWrap[0] . $result . $tableWrap[1];
                }
                }
-               return $code;
-       }       
+               return $result;
+       }
 
        /**
         * Constructs a table with content from the $arr1, $arr2 and $arr3.
         * Used in eg. ext/belog/mod/index.php - refer to that for examples
 
        /**
         * Constructs a table with content from the $arr1, $arr2 and $arr3.
         * Used in eg. ext/belog/mod/index.php - refer to that for examples
-        * 
+        *
         * @param       array           Menu elements on first level
         * @param       array           Secondary items
         * @param       array           Third-level items
         * @param       array           Menu elements on first level
         * @param       array           Secondary items
         * @param       array           Third-level items
@@ -1116,7 +1205,7 @@ $str.=$this->docBodyTagBegin().
         */
        function menuTable($arr1,$arr2=array(), $arr3=array())  {
                $rows = max(array(count($arr1),count($arr2),count($arr3)));
         */
        function menuTable($arr1,$arr2=array(), $arr3=array())  {
                $rows = max(array(count($arr1),count($arr2),count($arr3)));
-               
+
                $menu='
                <table border="0" cellpadding="0" cellspacing="0" id="typo3-tablemenu">';
                for($a=0;$a<$rows;$a++) {
                $menu='
                <table border="0" cellpadding="0" cellspacing="0" id="typo3-tablemenu">';
                for($a=0;$a<$rows;$a++) {
@@ -1142,7 +1231,7 @@ $str.=$this->docBodyTagBegin().
        /**
         * Returns a one-row/two-celled table with $content and $menu side by side.
         * The table is a 100% width table and each cell is aligned left / right
        /**
         * Returns a one-row/two-celled table with $content and $menu side by side.
         * The table is a 100% width table and each cell is aligned left / right
-        * 
+        *
         * @param       string          Content cell content (left)
         * @param       string          Menu cell content (right)
         * @return      string          HTML output
         * @param       string          Content cell content (left)
         * @param       string          Menu cell content (right)
         * @return      string          HTML output
@@ -1160,19 +1249,19 @@ $str.=$this->docBodyTagBegin().
        /**
         * Creates a selector box with clear-cache items.
         * Rather specialized functions - at least don't use it with $addSaveOptions unless you know what you do...
        /**
         * Creates a selector box with clear-cache items.
         * Rather specialized functions - at least don't use it with $addSaveOptions unless you know what you do...
-        * 
+        *
         * @param       integer         The page uid of the "current page" - the one that will be cleared as "clear cache for this page".
         * @param       boolean         If $addSaveOptions is set, then also the array of save-options for TCE_FORMS will appear.
         * @return      string          <select> tag with content - a selector box for clearing the cache
         */
        function clearCacheMenu($id,$addSaveOptions=0)  {
                global $BE_USER;
         * @param       integer         The page uid of the "current page" - the one that will be cleared as "clear cache for this page".
         * @param       boolean         If $addSaveOptions is set, then also the array of save-options for TCE_FORMS will appear.
         * @return      string          <select> tag with content - a selector box for clearing the cache
         */
        function clearCacheMenu($id,$addSaveOptions=0)  {
                global $BE_USER;
-               $opt=$addOptions;
+               $opt=array();
                if ($addSaveOptions)    {
                        $opt[]='<option value="">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.menu',1).'</option>';
                if ($addSaveOptions)    {
                        $opt[]='<option value="">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.menu',1).'</option>';
-                       $opt[]='<option value="TBE_EDITOR_checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc',1).'</option>';
-                       $opt[]='<option value="document.editform.closeDoc.value=-2; TBE_EDITOR_checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc',1).'</option>';
-                       if ($BE_USER->uc['allSaveFunctions'])   $opt[]='<option value="document.editform.closeDoc.value=-3; TBE_EDITOR_checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseAllDocs',1).'</option>';
+                       $opt[]='<option value="TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveDoc',1).'</option>';
+                       $opt[]='<option value="document.editform.closeDoc.value=-2; TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseDoc',1).'</option>';
+                       if ($BE_USER->uc['allSaveFunctions'])   $opt[]='<option value="document.editform.closeDoc.value=-3; TBE_EDITOR.checkAndDoSubmit(1);">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.saveCloseAllDocs',1).'</option>';
                        $opt[]='<option value="document.editform.closeDoc.value=2; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc',1).'</option>';
                        $opt[]='<option value="document.editform.closeDoc.value=3; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeAllDocs',1).'</option>';
                        $opt[]='<option value=""></option>';
                        $opt[]='<option value="document.editform.closeDoc.value=2; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeDoc',1).'</option>';
                        $opt[]='<option value="document.editform.closeDoc.value=3; document.editform.submit();">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:rm.closeAllDocs',1).'</option>';
                        $opt[]='<option value=""></option>';
@@ -1187,201 +1276,122 @@ $str.=$this->docBodyTagBegin().
                        } else if (this.options[this.selectedIndex].value.indexOf(\';\')!=-1) {
                                eval(this.options[this.selectedIndex].value);
                        }else{
                        } else if (this.options[this.selectedIndex].value.indexOf(\';\')!=-1) {
                                eval(this.options[this.selectedIndex].value);
                        }else{
-                               document.location=\''.$this->backPath.'tce_db.php?vC='.$BE_USER->veriCode().'&redirect='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')).'&cacheCmd=\'+this.options[this.selectedIndex].value;
+                               window.location.href=\''.$this->backPath.'tce_db.php?vC='.$BE_USER->veriCode().'&redirect='.rawurlencode(t3lib_div::getIndpEnv('REQUEST_URI')).'&cacheCmd=\'+this.options[this.selectedIndex].value;
                        }';
                $af_content = '<select name="cacheCmd" onchange="'.htmlspecialchars($onChange).'">'.implode('',$opt).'</select>';
 
                        }';
                $af_content = '<select name="cacheCmd" onchange="'.htmlspecialchars($onChange).'">'.implode('',$opt).'</select>';
 
-               if (count($opt)>2)      {
+               if (count($opt)>1)      {
                        return $af_content;
                }
        }
                        return $af_content;
                }
        }
-       
+
+
+       /**
+        * Includes a javascript library that exists in the core /typo3/ directory. The
+        * backpath is automatically applied
+        *
+        * @param       string          $lib: Library name. Call it with the full path
+        *                              like "contrib/prototype/prototype.js" to load it
+        * @return      void
+        */
+       function loadJavascriptLib($lib)        {
+               if (!isset($this->JScodeLibArray[$lib]))        {
+                       $this->JScodeLibArray[$lib] = '<script type="text/javascript" src="'.$this->backPath.$lib.'"></script>';
+               }
+       }
+
+
        /**
        /**
-        * Returns an array with parts (JavaScript, init-functions, <div>-layers) for use on pages which displays the clickmenu layers (context sensitive menus)
-        * 
-        * @return      array           If values are present: [0] = A <script> section for the HTML page header, [1] = onmousemove/onload handler for HTML tag or alike, [2] = Two empty <div> layers for the context menu
+        * Includes the necessary Javascript function for the clickmenu (context sensitive menus) in the document
+        *
+        * @return      array   Deprecated: Includes the code already in the doc, so the return array is always empty.
+        *                      Please just call this function without expecting a return value for future calls
         */
         */
-       function getContextMenuCode()   {
-               if ($this->isCMlayers())        {
-                       $content='
-                       <script type="text/javascript">
-                       /*<![CDATA[*/
-                               var GLV_gap=10;
-                               var GLV_curLayerX=new Array(0,0);
-                               var GLV_curLayerY=new Array(0,0);
-                               var GLV_curLayerWidth=new Array(0,0);
-                               var GLV_curLayerHeight=new Array(0,0);
-                               var GLV_isVisible=new Array(0,0);
-                               var GLV_x=0;
-                               var GLV_y=0;
-                               var GLV_xRel=0;
-                               var GLV_yRel=0;
-                               var layerObj=new Array();
-                               var layerObjCss=new Array();
-                               
-                                       //browsercheck...
-                               function GL_checkBrowser(){     //
-                                       this.dom= (document.getElementById);
-                                       this.op=  (navigator.userAgent.indexOf("Opera")>-1);
-                                       this.op7=  this.op && (navigator.appVersion.indexOf("7")>-1);  // check for Opera version 7
-                                       this.konq=  (navigator.userAgent.indexOf("Konq")>-1);
-                                       this.ie4= (document.all && !this.dom && !this.op && !this.konq);
-                                       this.ie5= (document.all && this.dom && !this.op && !this.konq);
-                                       this.ns4= (document.layers && !this.dom && !this.konq);
-                                       this.ns5= (!document.all && this.dom && !this.op && !this.konq);
-                                       this.ns6= (this.ns5);
-                                       this.bw=  (this.ie4 || this.ie5 || this.ns4 || this.ns6 || this.op || this.konq);
-                                       return this;
-                               }
-                               bw= new GL_checkBrowser();      
-                               
-                                       // GL_getObj(obj)
-                               function GL_getObj(obj){        //
-                                       nest="";
-                                       this.el= (bw.ie4||bw.op7)?document.all[obj]:bw.ns4?eval(nest+"document."+obj):document.getElementById(obj);     
-                                       this.css= bw.ns4?this.el:this.el.style;
-                                       this.ref= bw.ns4?this.el.document:document;             
-                                       this.x= (bw.ns4||bw.op)?this.css.left:this.el.offsetLeft;
-                                       this.y= (bw.ns4||bw.op)?this.css.top:this.el.offsetTop;
-                                       this.height= (bw.ie4||bw.ie5||bw.ns6||this.konq||bw.op7)?this.el.offsetHeight:bw.ns4?this.ref.height:bw.op?this.css.pixelHeight:0;
-                                       this.width= (bw.ie4||bw.ie5||bw.ns6||this.konq||bw.op7)?this.el.offsetWidth:bw.ns4?this.ref.width:bw.op?this.css.pixelWidth:0;
-                                       return this;
-                               }
-                                       // GL_getObjCss(obj)
-                               function GL_getObjCss(obj){     //
-                                       return bw.dom? document.getElementById(obj).style:bw.ie4?document.all[obj].style:bw.ns4?document.layers[obj]:0;
-                               }
-                                       // GL_getMouse(event)
-                               function GL_getMouse(event) {   //
-                                       if (layerObj)   {
-//                                             GLV_x= (bw.ns4||bw.ns5)?event.pageX:(bw.ie4||bw.op)?event.clientX:(event.clientX-2)+document.body.scrollLeft;
-//                                             GLV_y= (bw.ns4||bw.ns5)?event.pageY:(bw.ie4||bw.op)?event.clientY:(event.clientY-2)+document.body.scrollTop;
-                                                       // 17/12 2003: When documents run in XHTML standard compliance mode, the old scrollLeft/Top properties of document.body is gone - and for Opera/MSIE we have to use document.documentElement:
-                                               
-                                               GLV_xRel = event.clientX-2;
-                                               GLV_yRel = event.clientY-2;
-                                               GLV_x = GLV_xRel + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
-                                               GLV_y = GLV_yRel + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
-
-                                       //      status = (GLV_x+GLV_gap-GLV_curLayerX[0]) + " | " + (GLV_y+GLV_gap-GLV_curLayerY[0]);
-                                               if (GLV_isVisible[1])   {
-                                                       if (outsideLayer(1))    hideSpecific(1);
-                                               } else if (GLV_isVisible[0])    {
-                                                       if (outsideLayer(0))    hideSpecific(0);
-                                               }
-                                       }
-                               }
-                                       // outsideLayer(level)
-                               function outsideLayer(level)    {       //
-                                       return GLV_x+GLV_gap-GLV_curLayerX[level] <0 ||
-                                                       GLV_y+GLV_gap-GLV_curLayerY[level] <0 ||
-                                                       GLV_curLayerX[level]+GLV_curLayerWidth[level]+GLV_gap-GLV_x <0 ||
-                                                       GLV_curLayerY[level]+GLV_curLayerHeight[level]+GLV_gap-GLV_y <0;
-                               }
-                                       // setLayerObj(html,level)
-                               function setLayerObj(html,level)        {       //
-                                       var tempLayerObj = GL_getObj("contentMenu"+level);
-                                       var tempLayerObjCss = GL_getObjCss("contentMenu"+level);
-       
-                                       if (tempLayerObj && (level==0 || GLV_isVisible[level-1]))       {
-                                               tempLayerObj.el.innerHTML = html;
-                                               tempLayerObj.width= (bw.ie4||bw.ie5||bw.ns6||bw.konq||bw.op7)?this.el.offsetWidth:bw.ns4?this.ref.width:bw.op?this.css.pixelWidth:0;
-                                               tempLayerObj.height= (bw.ie4||bw.ie5||bw.ns6||bw.konq||bw.op7)?this.el.offsetHeight:bw.ns4?this.ref.height:bw.op?this.css.pixelHeight:0;
-                                               
-                                                       // Adjusting the Y-height of the layer to fit it into the window frame if it goes under the window frame in the bottom:
-                                               tempLayerObj.winHeight = document.documentElement.clientHeight && !bw.op7 ? document.documentElement.clientHeight : document.body.clientHeight;
-                                               if (tempLayerObj.winHeight-tempLayerObj.height < GLV_yRel)      { 
-                                                       if (GLV_yRel < tempLayerObj.height) {
-                                                               GLV_y+= (tempLayerObj.winHeight-tempLayerObj.height-GLV_yRel);          // Setting it so bottom is just above window height.
-                                                       } else {
-                                                               GLV_y-= tempLayerObj.height-8;          // Showing the menu upwards
-                                                       }
-                                               }
-                                               
-                                               GLV_curLayerX[level] = GLV_x;
-                                               GLV_curLayerY[level] = GLV_y;
-                                               tempLayerObjCss.left = GLV_x+"px";
-                                               tempLayerObjCss.top = GLV_y+"px";
-                                               tempLayerObjCss.visibility = "visible";
-                                               if (bw.ie5)     showHideSelectorBoxes("hidden");
-
-                                               GLV_isVisible[level]=1;
-                                               GLV_curLayerWidth[level] = tempLayerObj.width;
-                                               GLV_curLayerHeight[level] = tempLayerObj.height;
-                                       }
-                               }
-                                       // hideEmpty()
-                               function hideEmpty()    {       //
-                                       hideSpecific(0);
-                                       hideSpecific(1);
-                                       return false;
-                               }
-                                       // hideSpecific(level)
-                               function hideSpecific(level)    {       //
-                                       GL_getObjCss("contentMenu"+level).visibility = "hidden";
-                                       GL_getObj("contentMenu"+level).el.innerHTML = "";
-                                       GLV_isVisible[level]=0;
-                                       
-                                       if (bw.ie5 && level==0) showHideSelectorBoxes("visible");
-                               }
-                                       // debugObj(obj,name)
-                               function debugObj(obj,name)     {       //
-                                       var acc;
-                                       for (i in obj) {if (obj[i])     {acc+=i+":  "+obj[i]+"\n";}}                      
-                                       alert("Object: "+name+"\n\n"+acc);
-                               }
-                                       // initLayer()
-                               function initLayer(){   //
-                                       if (document.all)   {
-                                               window.onmousemove=GL_getMouse;
-                                       }
-                                       layerObj = GL_getObj("contentMenu1");
-                                       layerObjCss = GL_getObjCss("contentMenu1");
-                               }
-                               function showHideSelectorBoxes(action)  {       // This function by Michiel van Leening
-                                       for (i=0;i<document.forms.length;i++) {
-                                               for (j=0;j<document.forms[i].elements.length;j++) {
-                                                       if(document.forms[i].elements[j].type=="select-one") {
-                                                               document.forms[i].elements[j].style.visibility=action;
-                                                       }
-                                               }
-                                       }                                       
-                               }
-                       /*]]>*/
-                       </script>               
-                       ';
-                       return array(
-                               $content,
-                               ' onmousemove="GL_getMouse(event);" onload="initLayer();"',
-                               '<div id="contentMenu0" style="z-index:1; position:absolute;visibility:hidden"></div><div id="contentMenu1" style="z-index:2; position:absolute;visibility:hidden"></div>'
-                       );
-               } else return array('','','');
+       function getContextMenuCode()   {
+              $this->loadJavascriptLib('contrib/prototype/prototype.js');
+              $this->loadJavascriptLib('js/clickmenu.js');
+
+              $this->JScodeArray['clickmenu'] = '
+                              Clickmenu.clickURL = "'.$this->backPath.'alt_clickmenu.php";
+                              Clickmenu.ajax     = '.($this->isCMLayers() ? 'true' : 'false' ).';';
+
+                      // return array deprecated since 4.2
+              return array('','','');
        }
 
        }
 
+       /**
+        * Includes the necessary javascript file (tree.js) for use on pages which have the
+        * drag and drop functionality (usually pages and folder display trees)
+        *
+        * @param       string          indicator of which table the drag and drop function should work on (pages or folders)
+        * @return      array           If values are present: [0] = A <script> section for the HTML page header, [1] = onmousemove/onload handler for HTML tag or alike, [2] = One empty <div> layer for the follow-mouse drag element
+        */
+       function getDragDropCode($table)        {
+               $this->loadJavascriptLib('contrib/prototype/prototype.js');
+               $this->loadJavascriptLib('js/common.js');
+               $this->loadJavascriptLib('js/tree.js');
+
+                       // setting prefs for drag & drop
+               $this->JScodeArray['dragdrop'] = '
+                       DragDrop.changeURL = "'.$this->backPath.'alt_clickmenu.php";
+                       DragDrop.backPath  = "'.t3lib_div::shortMD5(''.'|'.$GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']).'";
+                       DragDrop.table     = "'.$table.'";
+               ';
 
 
+                      // return array deprecated since 4.2
+              return array('','','');
+       }
 
 
        /**
 
 
        /**
-        * creates a tab menu from an array definition
-        * 
+        * Creates a tab menu from an array definition
+        *
         * Returns a tab menu for a module
         * Requires the JS function jumpToUrl() to be available
         * Returns a tab menu for a module
         * Requires the JS function jumpToUrl() to be available
-        * 
-        * @param       string          $id is the "&id=" parameter value to be sent to the module
+        *
+        * @param       mixed           $id is the "&id=" parameter value to be sent to the module, but it can be also a parameter array which will be passed instead of the &id=...
         * @param       string          $elementName it the form elements name, probably something like "SET[...]"
         * @param       string          $currentValue is the value to be selected currently.
         * @param       array           $menuItems is an array with the menu items for the selector box
         * @param       string          $script is the script to send the &id to, if empty it's automatically found
         * @param       string          $addParams is additional parameters to pass to the script.
         * @return      string          HTML code for tab menu
         * @param       string          $elementName it the form elements name, probably something like "SET[...]"
         * @param       string          $currentValue is the value to be selected currently.
         * @param       array           $menuItems is an array with the menu items for the selector box
         * @param       string          $script is the script to send the &id to, if empty it's automatically found
         * @param       string          $addParams is additional parameters to pass to the script.
         * @return      string          HTML code for tab menu
-        * @todo        Update the HTML code to use the stylesheet.css instead.
-        * @author      RenĂ© Fritz <r.fritz@colorcube.de>
+        * @author      Rene Fritz <r.fritz@colorcube.de>
         */
         */
-       function getTabMenu($id,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
+       function getTabMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
                $content='';
 
                if (is_array($menuItems))       {
                $content='';
 
                if (is_array($menuItems))       {
+                       if (!is_array($mainParams)) {
+                               $mainParams = array('id' => $mainParams);
+                       }
+                       $mainParams = t3lib_div::implodeArrayForUrl('',$mainParams);
+
                        if (!$script) {$script=basename(PATH_thisScript);}
                        if (!$script) {$script=basename(PATH_thisScript);}
+
+                       $menuDef = array();
+                       foreach($menuItems as $value => $label) {
+                               $menuDef[$value]['isActive'] = !strcmp($currentValue,$value);
+                               $menuDef[$value]['label'] = t3lib_div::deHSCentities(htmlspecialchars($label));
+                               $menuDef[$value]['url'] = htmlspecialchars($script.'?'.$mainParams.$addparams.'&'.$elementName.'='.$value);
+                       }
+                       $content = $this->getTabMenuRaw($menuDef);
+
+               }
+               return $content;
+       }
+
+       /**
+        * Creates the HTML content for the tab menu
+        *
+        * @param       array           Menu items for tabs
+        * @return      string          Table HTML
+        * @access private
+        */
+       function getTabMenuRaw($menuItems)      {
+               $content='';
+
+               if (is_array($menuItems))       {
                        $options='';
 
                        $count = count($menuItems);
                        $options='';
 
                        $count = count($menuItems);
@@ -1396,85 +1406,527 @@ $str.=$this->docBodyTagBegin().
                        $widthRight = 100 - ($widthLeft + ($count*$widthNo) + $addToAct);
 
                        $first=true;
                        $widthRight = 100 - ($widthLeft + ($count*$widthNo) + $addToAct);
 
                        $first=true;
-                       foreach($menuItems as $value => $label) {
-                               $isActive = !strcmp($currentValue,$value);
-                               $class = $isActive ? "tabact" : "tab";
+                       foreach($menuItems as $id => $def) {
+                               $isActive = $def['isActive'];
+                               $class = $isActive ? 'tabact' : 'tab';
                                $width = $isActive ? $widthAct : $widthNo;
 
                                $width = $isActive ? $widthAct : $widthNo;
 
-                               $label = t3lib_div::deHSCentities(htmlspecialchars($label));
-                               $link = htmlspecialchars($script.'?id='.rawurlencode($id).$addparams.'&'.$elementName.'='.$value);
+                                       // @rene: Here you should probably wrap $label and $url in htmlspecialchars() in order to make sure its XHTML compatible! I did it for $url already since that is VERY likely to break.
+                               $label = $def['label'];
+                               $url = htmlspecialchars($def['url']);
+                               $params = $def['addParams'];
+
                                if($first) {
                                        $options.= '
                                if($first) {
                                        $options.= '
-                                                       <td width="'.$width.'%" class="'.$class.'" style="border-left: solid #000 1px;"><a href="'.$link.'" class="'.$class.'" style="padding-left:5px;padding-right:2px;">'.$label.'</a></td>';
+                                                       <td width="'.$width.'%" class="'.$class.'" style="border-left: solid #000 1px;"><a href="'.$url.'" style="padding-left:5px;padding-right:2px;" '.$params.'>'.$label.'</a></td>';
                                } else {
                                        $options.='
                                } else {
                                        $options.='
-                                                       <td width="'.$width.'%" class="'.$class.'"><a href="'.$link.'" class="'.$class.'">'.$label.'</a></td>';
+                                                       <td width="'.$width.'%" class="'.$class.'"><a href="'.$url.'" '.$params.'>'.$label.'</a></td>';
                                }
                                $first=false;
                        }
 
                        if ($options)   {
                                $content .= '
                                }
                                $first=false;
                        }
 
                        if ($options)   {
                                $content .= '
-                                       <!-- Tab menu -->
-                                       <table cellpadding="0" cellspacing="0" border="0" width="100%" id="typo3-tabmenu">
-                                               <tr>
+                               <!-- Tab menu -->
+                               <table cellpadding="0" cellspacing="0" border="0" width="100%" id="typo3-tabmenu">
+                                       <tr>
                                                        <td width="'.$widthLeft.'%">&nbsp;</td>
                                                        '.$options.'
                                                        <td width="'.$widthLeft.'%">&nbsp;</td>
                                                        '.$options.'
-                                                       <td width="'.$widthRight.'%">&nbsp;</td>
-                                               </tr>
-                                       </table>
-                                       <div class="hr" style="display:block;margin:0px;padding:0px;"></div>';
+                                               <td width="'.$widthRight.'%">&nbsp;</td>
+                                       </tr>
+                               </table>
+                               <div class="hr" style="margin:0px"></div>';
                        }
 
                        }
 
-                               // include CSS
-                       $actBgColor = t3lib_div::modifyHTMLcolorAll($this->bgColor6,0);
-                       $lgBgColor = t3lib_div::modifyHTMLcolorAll($this->bgColor5,25);
-                       $hoverBgColor = t3lib_div::modifyHTMLcolorAll($this->bgColor6,15);
+               }
+               return $content;
+       }
+
+       /**
+        * Creates a DYNAMIC tab-menu where the tabs are switched between with DHTML.
+        * Should work in MSIE, Mozilla, Opera and Konqueror. On Konqueror I did find a serious problem: <textarea> fields loose their content when you switch tabs!
+        *
+        * @param       array           Numeric array where each entry is an array in itself with associative keys: "label" contains the label for the TAB, "content" contains the HTML content that goes into the div-layer of the tabs content. "description" contains description text to be shown in the layer. "linkTitle" is short text for the title attribute of the tab-menu link (mouse-over text of tab). "stateIcon" indicates a standard status icon (see ->icon(), values: -1, 1, 2, 3). "icon" is an image tag placed before the text.
+        * @param       string          Identification string. This should be unique for every instance of a dynamic menu!
+        * @param       integer         If "1", then enabling one tab does not hide the others - they simply toggles each sheet on/off. This makes most sense together with the $foldout option. If "-1" then it acts normally where only one tab can be active at a time BUT you can click a tab and it will close so you have no active tabs.
+        * @param       boolean         If set, the tabs are rendered as headers instead over each sheet. Effectively this means there is no tab menu, but rather a foldout/foldin menu. Make sure to set $toggle as well for this option.
+        * @param       integer         Character limit for a new row.
+        * @param       boolean         If set, tab table cells are not allowed to wrap their content
+        * @param       boolean         If set, the tabs will span the full width of their position
+        * @param       integer         Default tab to open (for toggle <=0). Value corresponds to integer-array index + 1 (index zero is "1", index "1" is 2 etc.). A value of zero (or something non-existing) will result in no default tab open.
+        * @param       integer         If set to '1' empty tabs will be remove, If set to '2' empty tabs will be disabled
+        * @return      string          JavaScript section for the HTML header.
+        */
+       function getDynTabMenu($menuItems,$identString,$toggle=0,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1,$fullWidth=FALSE,$defaultTabIndex=1,$dividers2tabs=2)     {
+               // load the static code, if not already done with the function below
+               $this->loadJavascriptLib('js/tabmenu.js');
+
+               $content = '';
 
 
-                       $this->inDocStylesArray['getTabMenu'] = '
-                               td.tabact {
-                                       border: solid black 1px;
-                                       background: '.$actBgColor.';
-                                       color:#000;
+               if (is_array($menuItems))       {
+
+                               // Init:
+                       $options = array(array());
+                       $divs = array();
+                       $JSinit = array();
+                       $id = $this->getDynTabMenuId($identString);
+                       $noWrap = $noWrap ? ' nowrap="nowrap"' : '';
+
+                               // Traverse menu items
+                       $c=0;
+                       $tabRows=0;
+                       $titleLenCount = 0;
+                       foreach($menuItems as $index => $def) {
+                               $index+=1;      // Need to add one so checking for first index in JavaScript is different than if it is not set at all.
+
+                                       // Switch to next tab row if needed
+                               if (!$foldout && ($titleLenCount>$newRowCharLimit | ($def['newline'] === true && $titleLenCount > 0))) {
+                                       $titleLenCount=0;
+                                       $tabRows++;
+                                       $options[$tabRows] = array();
                                }
                                }
-                               td.tabact>a {
-                                       color:#000;
+
+                               if ($toggle==1) {
+                                       $onclick = 'this.blur(); DTM_toggle("'.$id.'","'.$index.'"); return false;';
+                               } else {
+                                       $onclick = 'this.blur(); DTM_activate("'.$id.'","'.$index.'", '.($toggle<0?1:0).'); return false;';
                                }
                                }
-                               td.tab {
-                                       border: solid #555 1px;
-                                       border-left: solid #aaa 3px;
-                                       background: '.$lgBgColor.';
-                                       color:grey;
+
+                               $isEmpty = !(strcmp(trim($def['content']),'') || strcmp(trim($def['icon']),''));
+
+                               // "Removes" empty tabs
+                               if ($isEmpty && $dividers2tabs == 1) {
+                                       continue;
                                }
                                }
-                               td.tab, td.tabact {
-                                       border-bottom: none;
-                                       border-radius: 3px;
-                                       -moz-border-radius: 3px;
+
+                               $mouseOverOut = ' onmouseover="DTM_mouseOver(this);" onmouseout="DTM_mouseOut(this);"';
+                               $requiredIcon = '<img name="' . $id . '-' . $index . '-REQ" src="' . $GLOBALS['BACK_PATH'] . 'gfx/clear.gif" width="10" height="10" hspace="4" alt="" />';
+
+                               if (!$foldout)  {
+                                               // Create TAB cell:
+                                       $options[$tabRows][] = '
+                                                       <td class="'.($isEmpty ? 'disabled' : 'tab').'" id="'.$id.'-'.$index.'-MENU"'.$noWrap.$mouseOverOut.'>'.
+                                                       ($isEmpty ? '' : '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>').
+                                                       $def['icon'].
+                                                       ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+                                                       $requiredIcon.
+                                                       $this->icons($def['stateIcon'],'margin-left: 10px;').
+                                                       ($isEmpty ? '' : '</a>').
+                                                       '</td>';
+                                       $titleLenCount+= strlen($def['label']);
+                               } else {
+                                               // Create DIV layer for content:
+                                       $divs[] = '
+                                               <div class="'.($isEmpty ? 'disabled' : 'tab').'" id="'.$id.'-'.$index.'-MENU"'.$mouseOverOut.'>'.
+                                                       ($isEmpty ? '' : '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>').
+                                                       $def['icon'].
+                                                       ($def['label'] ? htmlspecialchars($def['label']) : '&nbsp;').
+                                                       $requiredIcon.
+                                                       ($isEmpty ? '' : '</a>').
+                                                       '</div>';
                                }
                                }
-                               a.tab, a.tabact {
-                                       color:grey;
-                                       text-decoration:none;
-                                       display: block;
-                                       width:auto;
-                                       padding:2px;
-                                       padding-left:3px;
-                                       padding-right:5px;
+
+                                       // Create DIV layer for content:
+                               $divs[] = '
+                                               <div style="display: none;" id="'.$id.'-'.$index.'-DIV" class="c-tablayer">'.
+                                                       ($def['description'] ? '<p class="c-descr">'.nl2br(htmlspecialchars($def['description'])).'</p>' : '').
+                                                       $def['content'].
+                                                       '</div>';
+                                       // Create initialization string:
+                               $JSinit[] = '
+                                               DTM_array["'.$id.'"]['.$c.'] = "'.$id.'-'.$index.'";
+                               ';
+                                       // If not empty and we have the toggle option on, check if the tab needs to be expanded
+                               if ($toggle == 1 && !$isEmpty) {
+                                       $JSinit[] = '
+                                               if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'",1); }
+                                       ';
                                }
                                }
-                               a.tabact {
-                                       padding-left:10px;
-                                       padding-right:10px;
+
+                               $c++;
+                       }
+
+                               // Render menu:
+                       if (count($options))    {
+
+                                       // Tab menu is compiled:
+                               if (!$foldout)  {
+                                       $tabContent = '';
+                                       for($a=0;$a<=$tabRows;$a++)     {
+                                               $tabContent.= '
+
+                                       <!-- Tab menu -->
+                                       <table cellpadding="0" cellspacing="0" border="0"'.($fullWidth ? ' width="100%"' : '').' class="typo3-dyntabmenu">
+                                               <tr>
+                                                               '.implode('',$options[$a]).'
+                                               </tr>
+                                       </table>';
+                                       }
+                                       $content.= '<div class="typo3-dyntabmenu-tabs">'.$tabContent.'</div>';
                                }
                                }
-                               a.tab:hover,a.tabact:hover {
-                                       color:black;
-                                       background: '.$hoverBgColor.';
-                                       text-decoration:none;
-                                       cursor: pointer;
-                               }';
+
+                                       // Div layers are added:
+                               $content.= '
+                               <!-- Div layers for tab menu: -->
+                               <div class="typo3-dyntabmenu-divs'.($foldout?'-foldout':'').'">
+                               '.implode('',$divs).'</div>';
+
+                                       // Java Script section added:
+                               $content.= '
+                               <!-- Initialization JavaScript for the menu -->
+                               <script type="text/javascript">
+                                       DTM_array["'.$id.'"] = new Array();
+                                       '.implode('',$JSinit).'
+                                       '.($toggle<=0 ? 'DTM_activate("'.$id.'", top.DTM_currentTabs["'.$id.'"]?top.DTM_currentTabs["'.$id.'"]:'.intval($defaultTabIndex).', 0);' : '').'
+                               </script>
+
+                               ';
+                       }
+
                }
                return $content;
        }
                }
                return $content;
        }
-}
 
 
+       /**
+        * Creates the id for dynTabMenus.
+        *
+        * @param       string          $identString: Identification string. This should be unique for every instance of a dynamic menu!
+        * @return      string          The id with a short MD5 of $identString and prefixed "DTM-", like "DTM-2e8791854a"
+        */
+       function getDynTabMenuId($identString) {
+               $id = 'DTM-'.t3lib_div::shortMD5($identString);
+               return $id;
+       }
+
+       /**
+        * Returns dynamic tab menu header JS code.
+        * This is now incorporated automatically when the function template::getDynTabMenu is called
+        * (as long as it is called before $this->startPage())
+        * The return value is not needed anymore
+        *
+        * @return      string          JavaScript section for the HTML header. (return value is deprecated since TYPO3 4.3, will be removed in TYPO3 4.5)
+        */
+       function getDynTabMenuJScode()  {
+               $this->loadJavascriptLib('js/tabmenu.js');
+               // return value deprecated since TYPO3 4.3
+               return '';
+       }
+
+       /**
+        * Creates the version selector for the page id inputted.
+        * Requires the core version management extension, "version" to be loaded.
+        *
+        * @param       integer         Page id to create selector for.
+        * @param       boolean         If set, there will be no button for swapping page.
+        * @return      void
+        */
+       function getVersionSelector($id,$noAction=FALSE)        {
+
+               if ($id>0)      {
+                       if (t3lib_extMgm::isLoaded('version') && $GLOBALS['BE_USER']->workspace==0)     {
+
+                                       // Get Current page record:
+                               $curPage = t3lib_BEfunc::getRecord('pages',$id);
+                                       // If the selected page is not online, find the right ID
+                               $onlineId = ($curPage['pid']==-1 ? $curPage['t3ver_oid'] : $id);
+                                       // Select all versions of online version:
+                               $versions = t3lib_BEfunc::selectVersionsOfRecord('pages', $onlineId, 'uid,pid,t3ver_label,t3ver_oid,t3ver_wsid,t3ver_id');
+
+                                       // If more than one was found...:
+                               if (count($versions)>1) {
+
+                                               // Create selector box entries:
+                                       $opt = array();
+                                       foreach($versions as $vRow)     {
+                                               $opt[] = '<option value="'.htmlspecialchars(t3lib_div::linkThisScript(array('id'=>$vRow['uid']))).'"'.($id==$vRow['uid']?' selected="selected"':'').'>'.
+                                                               htmlspecialchars($vRow['t3ver_label'].' [v#'.$vRow['t3ver_id'].', WS:'.$vRow['t3ver_wsid'].']'.($vRow['uid']==$onlineId ? ' =>'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.online').'<=':'')).
+                                                               '</option>';
+                                       }
+
+                                               // Add management link:
+                                       $opt[] = '<option value="'.htmlspecialchars(t3lib_div::linkThisScript(array('id'=>$id))).'">---</option>';
+                                       $opt[] = '<option value="'.htmlspecialchars($this->backPath.t3lib_extMgm::extRelPath('version').'cm1/index.php?table=pages&uid='.$onlineId).'">'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.mgm',1).'</option>';
+
+                                               // Create onchange handler:
+                                       $onChange = "window.location.href=this.options[this.selectedIndex].value;";
+
+                                               // Controls:
+                                       if ($id==$onlineId)     {
+                                               $controls = '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/blinkarrow_left.gif','width="5" height="9"').' class="absmiddle" alt="" /> <b>'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.online',1).'</b>';
+                                       } elseif (!$noAction) {
+                                               $controls = '<a href="'.$this->issueCommand('&cmd[pages]['.$onlineId.'][version][swapWith]='.$id.'&cmd[pages]['.$onlineId.'][version][action]=swap',t3lib_div::linkThisScript(array('id'=>$onlineId))).'" class="nobr">'.
+                                                               '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/insert1.gif','width="14" height="14"').' style="margin-right: 2px;" class="absmiddle" alt="" title="'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swapPage',1).'" />'.
+                                                               '<b>'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.swap',1).'</b></a>';
+                                       }
+
+                                               // Write out HTML code:
+                                       return '
+
+                                               <!--
+                                                       Version selector:
+                                               -->
+                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
+                                                       <tr>
+                                                               <td>'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.selVer',1).'</td>
+                                                               <td>
+                                                                       <select onchange="'.htmlspecialchars($onChange).'">
+                                                                               '.implode('',$opt).'
+                                                                       </select></td>
+                                                               <td>'.$controls.'</td>
+                                                       </tr>
+                                               </table>
+                                       ';
+                               }
+                       } elseif ($GLOBALS['BE_USER']->workspace!==0) {
+
+                                       // Write out HTML code:
+                               switch($GLOBALS['BE_USER']->workspace)  {
+                                       case 0:
+                                               $wsTitle = 'LIVE';
+                                       break;
+                                       case -1:
+                                               $wsTitle = 'Draft';
+                                       break;
+                                       default:
+                                               $wsTitle = $GLOBALS['BE_USER']->workspaceRec['title'];
+                                       break;
+                               }
+
+                               if (t3lib_BEfunc::isPidInVersionizedBranch($id)=='branchpoint') {
+                                       return '
+
+                                               <!--
+                                                       Version selector:
+                                               -->
+                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
+                                                       <tr>
+                                                               <td>Workspace: "'.htmlspecialchars($wsTitle).'"</td>
+                                                               <td><em>Inside branch, no further versioning possible</em></td>
+                                                       </tr>
+                                               </table>
+                                       ';
+                               } else {
+                                               // Get Current page record:
+                                       $curPage = t3lib_BEfunc::getRecord('pages',$id);
+                                               // If the selected page is not online, find the right ID
+                                       $onlineId = ($curPage['pid']==-1 ? $curPage['t3ver_oid'] : $id);
+                                               // The version of page:
+                                       $verPage = t3lib_BEfunc::getWorkspaceVersionOfRecord($GLOBALS['BE_USER']->workspace, 'pages', $onlineId);
+
+                                       if (!$verPage)  {
+
+                                               if (!count(t3lib_BEfunc::countVersionsOfRecordsOnPage($GLOBALS['BE_USER']->workspace, $onlineId)))      {
+                                                       if ($GLOBALS['BE_USER']->workspaceVersioningTypeAccess(0))      {
+
+                                                               $onClick = $this->issueCommand('&cmd[pages]['.$onlineId.'][version][action]=new&cmd[pages]['.$onlineId.'][version][treeLevels]=0',t3lib_div::linkThisScript(array('id'=>$onlineId)));
+                                                               $onClick = 'window.location.href=\''.$onClick.'\'; return false;';
+                                                                       // Write out HTML code:
+                                                               return '
+
+                                                                       <!--
+                                                                               No version yet, create one?
+                                                                       -->
+                                                                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
+                                                                               <tr>
+                                                                                       <td>Workspace: "'.htmlspecialchars($wsTitle).'"</td>
+                                                                                       <td>
+                                                                                               <input type="submit" value="New version of page" name="_" onclick="'.htmlspecialchars($onClick).'" /></td>
+                                                                               </tr>
+                                                                       </table>
+                                                               ';
+                                                       }
+                                               } else {
+                                                       return '
+
+                                                               <!--
+                                                                       Version selector:
+                                                               -->
+                                                               <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
+                                                                       <tr>
+                                                                               <td>Workspace: "'.htmlspecialchars($wsTitle).'"</td>
+                                                                               <td><em>Versions found on page, no "Page" versioning possible</em></td>
+                                                                       </tr>
+                                                               </table>
+                                                       ';
+                                               }
+                                       } elseif ($verPage['t3ver_swapmode']==0) {
+                                               $onClick = $this->issueCommand('&cmd[pages]['.$onlineId.'][version][action]=swap&cmd[pages]['.$onlineId.'][version][swapWith]='.$verPage['uid'],t3lib_div::linkThisScript(array('id'=>$onlineId)));
+                                               $onClick = 'window.location.href=\''.$onClick.'\'; return false;';
+
+                                                       // Write out HTML code:
+                                               return '
+
+                                                       <!--
+                                                               Version selector:
+                                                       -->
+                                                       <table border="0" cellpadding="0" cellspacing="0" id="typo3-versionSelector">
+                                                               <tr>
+                                                                       <td>Workspace: "'.htmlspecialchars($wsTitle).'"</td>
+                                                                       <td>
+                                                                               <input type="submit" value="Publish page" name="_" onclick="'.htmlspecialchars($onClick).'" /></td>
+                                                               </tr>
+                                                       </table>
+                                               ';
+                                       }
+                               }
+                       }
+               }
+       }
+
+
+       /**
+        * Function to load a HTML template file with markers.
+        *
+        * @param       string          tmpl name, usually in the typo3/template/ directory
+        * @return      string          HTML of template
+        */
+       function getHtmlTemplate($filename)     {
+               if ($GLOBALS['TBE_STYLES']['htmlTemplates'][$filename]) {
+                       $filename = $GLOBALS['TBE_STYLES']['htmlTemplates'][$filename];
+               }
+               return ($filename ? t3lib_div::getURL(t3lib_div::resolveBackPath($this->backPath . $filename)) : '');
+       }
+
+       /**
+        * Define the template for the module
+        *
+        * @param       string          filename
+        */
+       function setModuleTemplate($filename) {
+                       // Load Prototype lib for IE event
+               $this->loadJavascriptLib('contrib/prototype/prototype.js');
+               $this->loadJavascriptLib('js/iecompatibility.js');
+               $this->moduleTemplate = $this->getHtmlTemplate($filename);
+       }
+
+       /**
+        * Put together the various elements for the module <body> using a static HTML
+        * template
+        *
+        * @param       array           Record of the current page, used for page path and info
+        * @param       array           HTML for all buttons
+        * @param       array           HTML for all other markers
+        * @return      string          Composite HTML
+        */
+       public function moduleBody($pageRecord = array(), $buttons = array(), $markerArray = array(), $subpartArray = array()) {
+                       // Get the HTML template for the module
+               $moduleBody = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###FULLDOC###');
+                       // Add CSS
+               $this->inDocStylesArray[] = 'html { overflow: hidden; }';
+                       // Add JS code to the <head> for IE
+               $this->JScode.= $this->wrapScriptTags('
+                               // workaround since IE6 cannot deal with relative height for scrolling elements
+                       function resizeDocBody()        {
+                               $("typo3-docbody").style.height = (document.body.offsetHeight - parseInt($("typo3-docheader").getStyle("height")));
+                       }
+                       if (Prototype.Browser.IE) {
+                               var version = parseFloat(navigator.appVersion.split(\';\')[1].strip().split(\' \')[1]);
+                               if (version == 6) {
+                                       Event.observe(window, "resize", resizeDocBody, false);
+                                       Event.observe(window, "load", resizeDocBody, false);
+                               }
+                       }
+               ');
+                       // Get the page path for the docheader
+               $markerArray['PAGEPATH'] = $this->getPagePath($pageRecord);
+                       // Get the page info for the docheader
+               $markerArray['PAGEINFO'] = $this->getPageInfo($pageRecord);
+                       // Get all the buttons for the docheader
+               $docHeaderButtons = $this->getDocHeaderButtons($buttons);
+                       // Merge docheader buttons with the marker array
+               $markerArray = array_merge($markerArray, $docHeaderButtons);
+                       // replacing subparts
+               foreach ($subpartArray as $marker => $content) {
+                       $moduleBody = t3lib_parsehtml::substituteSubpart($moduleBody, $marker, $content);
+               }
+                       // replacing all markers with the finished markers and return the HTML content
+               return t3lib_parsehtml::substituteMarkerArray($moduleBody, $markerArray, '###|###');
+
+       }
+
+       /**
+        * Fill the button lists with the defined HTML
+        *
+        * @param       array           HTML for all buttons
+        * @return      array           Containing HTML for both buttonlists
+        */
+       protected function getDocHeaderButtons($buttons) {
+               $markers = array();
+                       // Fill buttons for left and right float
+               $floats = array('left', 'right');
+               foreach($floats as $key) {
+                               // Get the template for each float
+                       $buttonTemplate = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUPS_' . strtoupper($key) . '###');
+                               // Fill the button markers in this float
+                       $buttonTemplate = t3lib_parsehtml::substituteMarkerArray($buttonTemplate, $buttons, '###|###', true);
+                               // getting the wrap for each group
+                       $buttonWrap = t3lib_parsehtml::getSubpart($this->moduleTemplate, '###BUTTON_GROUP_WRAP###');
+                               // looping through the groups (max 6) and remove the empty groups
+                       for ($groupNumber = 1; $groupNumber < 6; $groupNumber++) {
+                               $buttonMarker = '###BUTTON_GROUP' . $groupNumber . '###';
+                               $buttonGroup = t3lib_parsehtml::getSubpart($buttonTemplate, $buttonMarker);
+                               if (trim($buttonGroup)) {
+                                       if ($buttonWrap) {
+                                               $buttonGroup = t3lib_parsehtml::substituteMarker($buttonWrap, '###BUTTONS###', $buttonGroup);
+                                       }
+                                       $buttonTemplate = t3lib_parsehtml::substituteSubpart($buttonTemplate, $buttonMarker, trim($buttonGroup));
+                               }
+                       }
+                               // replace the marker with the template and remove all line breaks (for IE compat)
+                       $markers['BUTTONLIST_' . strtoupper($key)] = str_replace("\n", '', $buttonTemplate);
+               }
+               return $markers;
+       }
+
+       /**
+        * Generate the page path for docheader
+        *
+        * @param       array   Current page
+        * @return      string  Page path
+        */
+       protected function getPagePath($pageRecord) {
+               global $LANG;
+                       // Is this a real page
+               if ($pageRecord['uid']) {
+                       $title = $pageRecord['_thePath'];
+               } else {
+                       $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
+               }
+                       // Setting the path of the page
+               $pagePath = $LANG->sL('LLL:EXT:lang/locallang_core.php:labels.path', 1) . ': <span class="typo3-docheader-pagePath">' . htmlspecialchars(t3lib_div::fixed_lgd_cs($title, -50)) . '</span>';
+               return $pagePath;
+       }
+
+       /**
+        * Setting page icon with clickmenu + uid for docheader
+        *
+        * @param       array   Current page
+        * @return      string  Page info
+        */
+       protected function getPageInfo($pageRecord) {
+               global $BE_USER;
+                               // Add icon with clickmenu, etc:
+               if ($pageRecord['uid']) {       // If there IS a real page
+                       $alttext = t3lib_BEfunc::getRecordIconAltText($pageRecord, 'pages');
+                       $iconImg = t3lib_iconWorks::getIconImage('pages', $pageRecord, $this->backPath, 'class="absmiddle" title="'. htmlspecialchars($alttext) . '"');
+                               // Make Icon:
+                       $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', $pageRecord['uid']);
+               } else {        // On root-level of page tree
+                               // Make Icon
+                       $iconImg = '<img' . t3lib_iconWorks::skinImg($this->backPath, 'gfx/i/_icon_website.gif') . ' alt="' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . '" />';
+                       if($BE_USER->user['admin']) {
+                               $theIcon = $GLOBALS['SOBE']->doc->wrapClickMenuOnIcon($iconImg, 'pages', 0);
+                       } else {
+                               $theIcon = $iconImg;
+                       }
+               }
+
+                       // Setting icon with clickmenu + uid
+               $pageInfo = $theIcon . '<em>[pid: ' . $pageRecord['uid'] . ']</em>';
+               return $pageInfo;
+       }
+}
 
 
 // ******************************
 
 
 // ******************************
@@ -1487,7 +1939,7 @@ $str.=$this->docBodyTagBegin().
 /**
  * Extension class for "template" - used for backend pages which are wide. Typically modules taking up all the space in the "content" frame of the backend
  * The class were more significant in the past than today.
 /**
  * Extension class for "template" - used for backend pages which are wide. Typically modules taking up all the space in the "content" frame of the backend
  * The class were more significant in the past than today.
- * 
+ *
  */
 class bigDoc extends template {
        var $divClass = 'typo3-bigDoc';
  */
 class bigDoc extends template {
        var $divClass = 'typo3-bigDoc';
@@ -1496,7 +1948,7 @@ class bigDoc extends template {
 /**
  * Extension class for "template" - used for backend pages without the "document" background image
  * The class were more significant in the past than today.
 /**
  * Extension class for "template" - used for backend pages without the "document" background image
  * The class were more significant in the past than today.
- * 
+ *
  */
 class noDoc extends template {
        var $divClass = 'typo3-noDoc';
  */
 class noDoc extends template {
        var $divClass = 'typo3-noDoc';
@@ -1505,7 +1957,7 @@ class noDoc extends template {
 /**
  * Extension class for "template" - used for backend pages which were narrow (like the Web>List modules list frame. Or the "Show details" pop up box)
  * The class were more significant in the past than today.
 /**
  * Extension class for "template" - used for backend pages which were narrow (like the Web>List modules list frame. Or the "Show details" pop up box)
  * The class were more significant in the past than today.
- * 
+ *
  */
 class smallDoc extends template {
        var $divClass = 'typo3-smallDoc';
  */
 class smallDoc extends template {
        var $divClass = 'typo3-smallDoc';
@@ -1514,32 +1966,22 @@ class smallDoc extends template {
 /**
  * Extension class for "template" - used for backend pages which were medium wide. Typically submodules to Web or File which were presented in the list-frame when the content frame were divided into a navigation and list frame.
  * The class were more significant in the past than today. But probably you should use this one for most modules you make.
 /**
  * Extension class for "template" - used for backend pages which were medium wide. Typically submodules to Web or File which were presented in the list-frame when the content frame were divided into a navigation and list frame.
  * The class were more significant in the past than today. But probably you should use this one for most modules you make.
- * 
+ *
  */
 class mediumDoc extends template {
        var $divClass = 'typo3-mediumDoc';
 }
 
 
  */
 class mediumDoc extends template {
        var $divClass = 'typo3-mediumDoc';
 }
 
 
-
-// Include extension to the template class?
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php'])     {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php']);
 }
 
 
 
 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php'])     {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/template.php']);
 }
 
 
 
-// ******************************************************
-// The backend language engine is started (ext: "lang")
-// ******************************************************
-require_once(PATH_typo3.'sysext/lang/lang.php');
-$LANG = t3lib_div::makeInstance('language');
-$LANG->init($BE_USER->uc['lang']);
-
-
-
 // ******************************
 // The template is loaded
 // ******************************
 // ******************************
 // The template is loaded
 // ******************************
-$TBE_TEMPLATE = t3lib_div::makeInstance('template');
+$GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
+
 ?>
 ?>