Cleanup: Updated copyright notices
[Packages/TYPO3.CMS.git] / typo3 / template.php
index 26cd904..4aa9c2d 100755 (executable)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 1999-2004 Kasper Skaarhoj (kasper@typo3.com)
+*  (c) 1999-2009 Kasper Skaarhoj (kasperYYYY@typo3.com)
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
  * 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]
  *
- *  133: function fw($str)
+ *  145: function fw($str)
  *
  *
- *  157: class template
- *  212:     function template()
+ *  169: class template
+ *  224:     function template()
  *
  *              SECTION: EVALUATION FUNCTIONS
- *  284:     function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='')
- *  301:     function viewPageIcon($id,$backPath,$addParams='hspace="3"')
- *  326:     function issueCommand($params,$rUrl='')
- *  341:     function isCMlayers()
- *  351:     function thisBlur()
- *  361:     function helpStyle()
- *  378:     function getHeader($table,$row,$path,$noViewPageIcon=0,$tWrap=array('',''))
- *  404:     function getFileheader($title,$path,$iconfile)
- *  419:     function makeShortcutIcon($gvList,$setList,$modName,$motherModName="")
- *  452:     function makeShortcutUrl($gvList,$setList)
- *  473:     function formWidth($size=48,$textarea=0,$styleOverride='')
- *  498:     function formWidthText($size=48,$styleOverride='',$wrap='')
- *  515:     function redirectUrls($thisLocation='')
- *  539:     function formatTime($tstamp,$type)
- *  552:     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.
- *  585:     function startPage($title)
- *  660:     function endPage()
- *  689:     function header($text)
- *  710:     function section($label,$text,$nostrtoupper=FALSE,$sH=FALSE,$type=0,$allowHTMLinHeader=FALSE)
- *  734:     function divider($dist)
- *  750:     function spacer($dist)
- *  769:     function sectionHeader($label,$sH=FALSE,$addAttrib='')
- *  786:     function sectionBegin()
- *  807:     function sectionEnd()
- *  827:     function middle()
- *  836:     function endPageJS()
- *  853:     function docBodyTagBegin()
- *  863:     function docStyle()
- *  904:     function insertStylesAndJS($content)
- *  924:     function initCharset()
- *  936:     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
- *  968:     function icons($type)
- *  997:     function t3Button($onClick,$label)
- * 1008:     function dfw($string)
- * 1018:     function rfw($string)
- * 1028:     function wrapInCData($string)
- * 1045:     function wrapScriptTags($string, $linebreak=TRUE)
- * 1082:     function table($arr)
- * 1122:     function menuTable($arr1,$arr2=array(), $arr3=array())
- * 1155:     function funcMenu($content,$menu)
- * 1173:     function clearCacheMenu($id,$addSaveOptions=0)
- * 1209:     function getContextMenuCode()
- * 1385:     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)
  *
  *
- * 1497: class bigDoc extends template
+ * 2060: class bigDoc extends template
  *
  *
- * 1506: class noDoc extends template
+ * 2069: class noDoc extends template
  *
  *
- * 1515: class smallDoc extends template
+ * 2078: class smallDoc extends template
  *
  *
- * 1524: 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")
  *
  */
 
 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)
- * @depreciated
+ * @deprecated since TYPO3 3.6
  */
 function fw($str)      {
        return $str;
@@ -150,7 +162,7 @@ function fw($str)   {
  *
  * 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
  */
@@ -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.
+       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 $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 $docType = '';                              // Doc-type used in the header. Default is HTML 4. 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.
@@ -173,6 +188,7 @@ class template {
        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.
+       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
@@ -213,7 +229,11 @@ class 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/..."
                }
@@ -284,9 +304,9 @@ class template {
         * @return      string          The link-wrapped input string.
         */
        function wrapClickMenuOnIcon($str,$table,$uid='',$listFr=1,$addParams='',$enDisItems='', $returnOnClick=FALSE)  {
-               $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.'|'.$enDisItems).$backPath.$addParams.'\');'.$this->thisBlur().'return false;';
-               return $returnOnClick ? $onClick : '<a href="#" onclick="'.htmlspecialchars($onClick).'">'.$str.'</a>';
+               $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>';
        }
 
        /**
@@ -342,7 +362,7 @@ class template {
         * @return      boolean
         */
        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');
        }
 
        /**
@@ -424,21 +444,25 @@ class template {
                $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);
-               } else $mMN="";
+               } 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;';
+               $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>';
+               $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;
        }
 
@@ -456,7 +480,7 @@ class template {
                $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;
@@ -468,7 +492,7 @@ class template {
         * 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       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()
@@ -540,10 +564,14 @@ class template {
         * @return      string          Formatted timestamp
         */
        function formatTime($tstamp,$type)      {
+               $dateStr = '';
                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;
        }
 
        /**
@@ -586,6 +614,19 @@ class template {
         * @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();
@@ -597,32 +638,39 @@ class template {
                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':
-                               $headerStart= '<!DOCTYPE html
+                               $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"?>
 ';
-                       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':
-                               $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.'"?>
 ';
-                       break;
+                               break;
+                       // The fallthrough is intended as XHTML 1.0 transitional is the default for the BE.
+                       case 'xhtml_trans':
                        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.
@@ -634,13 +682,17 @@ class template {
        '.$generator.'
        <title>'.htmlspecialchars($title).'</title>
        '.$this->docStyle().'
+       '.implode("\n", $this->JScodeLibArray).'
        '.$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>
 ';
-               $this->JScode='';
-               $this->JScodeArray=array();
+               $this->JScodeLibArray = array();
+               $this->JScode = $this->extJsCode = '';
+               $this->JScodeArray = array();
 
                if ($this->docType=='xhtml_frames')     {
                        return $str;
@@ -664,20 +716,25 @@ $str.=$this->docBodyTagBegin().
                $str = $this->sectionEnd().
                                $this->postCode.
                                $this->endPageJS().
-                               t3lib_BEfunc::getSetUpdateSignal().
+                               $this->wrapScriptTags(t3lib_BEfunc::getUpdateSignalCode()).
                                $this->parseTime().
                                ($this->form?'
-</form>':'').
-                               ($this->divClass?'
+</form>':'');
+
+               if ($this->docType!='xhtml_frames') {
+
+                       $str .= ($this->divClass?'
 
 <!-- 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','',0,array('_FLUSH'=>TRUE));
+               if (TYPO3_DLOG) t3lib_div::devLog('END of BACKEND session', 'template', 0, array('_FLUSH' => true));
 
                return $str;
        }
@@ -747,7 +804,7 @@ $str.=$this->docBodyTagBegin().
        /**
         * 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)  {
@@ -821,11 +878,11 @@ $str.=$this->docBodyTagBegin().
 
        /**
         * Originally it printed a kind of divider.
-        * Depreciated. Just remove function calls to it or call the divider() function instead.
+        * Deprecated. Just remove function calls to it or call the divider() function instead.
         *
         * @return      void
         * @internal
-        * @depreciated
+        * @deprecated since TYPO3 3.6
         */
        function middle()       {
        }
@@ -854,7 +911,7 @@ $str.=$this->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).'>';
        }
 
@@ -888,7 +945,8 @@ $str.=$this->docBodyTagBegin().
                                        /*###POSTCSSMARKER###*/
                                /*]]>*/
                        </style>
-                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'')
+                       '.($this->styleSheetFile_post?'<link rel="stylesheet" type="text/css" href="'.$this->backPath.$this->styleSheetFile_post.'" />':'').'
+                       '.implode("\n", $this->additionalStyleSheets)
                )
                ;
                $this->inDocStyles='';
@@ -899,6 +957,21 @@ $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
         * This is needed for extobjbase
         *
@@ -935,11 +1008,11 @@ $str.=$this->docBodyTagBegin().
        /**
         * Returns generator meta tag
         *
-        * @return      string          <meta> tag with name "GENERATOR"
+        * @return      string          <meta> tag with name "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 .'" />';
        }
 
 
@@ -1055,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
+                       $match = array();
                        if(preg_match('/^(\t+)/',$string,$match)) {
                                $string = str_replace($match[1],"\t", $string);
                        }
@@ -1069,52 +1143,55 @@ $str.=$this->docBodyTagBegin().
 
                // These vars defines the layout for the table produced by the table() function.
                // 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">';
 
        /**
-        * 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           If set, then this provides an alternative layout array instead of $this->tableLayout
         * @return      string          The HTML table.
         * @internal
         */
-       function table($arr, $layout='')        {
-               if (is_array($arr))     {
-                       $tableLayout = (is_array($layout)) ? $layout : $this->tableLayout;
-
-                       reset($arr);
-                       $code='';
-                       $rc=0;
-                       while(list(,$val)=each($arr))   {
-                               if ($rc % 2) {
+       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 {
                                        $layout = is_array($tableLayout['defRowEven']) ? $tableLayout['defRowEven'] : $tableLayout['defRow'];
                                }
-                               $layoutRow = is_array($tableLayout[$rc]) ? $tableLayout[$rc] : $layout;
-                               $code_td='';
-                               if (is_array($val))     {
-                                       $cc=0;
-                                       while(list(,$content)=each($val))       {
-                                               $wrap= is_array($layoutRow[$cc]) ? $layoutRow[$cc] : (is_array($layoutRow['defCol']) ? $layoutRow['defCol'] : (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($layoutRow['tr']) ? $layoutRow['tr'] : (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($tableLayout['table']) ? $tableLayout['table'] : array($this->table_TABLE, '</table>');
-                       $code=$tableWrap[0].$code.$tableWrap[1];
+                       $result = $tableWrap[0] . $result . $tableWrap[1];
                }
-               return $code;
+               return $result;
        }
 
        /**
@@ -1179,12 +1256,12 @@ $str.=$this->docBodyTagBegin().
         */
        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>';
-                       $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>';
@@ -1199,192 +1276,73 @@ $str.=$this->docBodyTagBegin().
                        } 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>';
 
-               if (count($opt)>2)      {
+               if (count($opt)>1)      {
                        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)
+        * Includes the necessary Javascript function for the clickmenu (context sensitive menus) in the document
         *
-        * @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
+        * @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 winHeight = document.documentElement.clientHeight && !bw.op7 ? document.documentElement.clientHeight : document.body.clientHeight;
-                                       var winWidth = document.documentElement.clientWidth && !bw.op7 ? document.documentElement.clientWidth : document.body.clientWidth;
-                                       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;
-
-                                                       // konqueror (3.2.2) workaround
-                                               winHeight = (bw.konq)?window.innerHeight:winHeight;
-                                               winWidth = (bw.konq)?window.innerWidth:winWidth;
-
-                                                       // Adjusting the Y-height of the layer to fit it into the window frame if it goes under the window frame in the bottom:
-                                               if (winHeight-tempLayerObj.height < GLV_yRel)   {
-                                                       if (GLV_yRel < tempLayerObj.height) {
-                                                               GLV_y+= (winHeight-tempLayerObj.height-GLV_yRel);               // Setting it so bottom is just above window height.
-                                                       } else {
-                                                               GLV_y-= tempLayerObj.height-8;          // Showing the menu upwards
-                                                       }
-                                               }
-                                                       // Adjusting the X position like Y above
-                                               if (winWidth-tempLayerObj.width < GLV_xRel)     {
-                                                       if (GLV_xRel < tempLayerObj.width) {
-                                                               GLV_x+= (winWidth-tempLayerObj.width-GLV_xRel);
-                                                       } else {
-                                                               GLV_x-= tempLayerObj.width-8;
-                                                       }
-                                               }
-                                               GLV_x = Math.max(GLV_x,1);
-                                               GLV_y = Math.max(GLV_y,1);
-
-                                               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;
+       function getContextMenuCode()   {
+              $this->loadJavascriptLib('contrib/prototype/prototype.js');
+              $this->loadJavascriptLib('js/clickmenu.js');
 
-                                       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('','','');
+              $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
         *
@@ -1398,7 +1356,7 @@ $str.=$this->docBodyTagBegin().
         * @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
-        * @author      René Fritz <r.fritz@colorcube.de>
+        * @author      Rene Fritz <r.fritz@colorcube.de>
         */
        function getTabMenu($mainParams,$elementName,$currentValue,$menuItems,$script='',$addparams='') {
                $content='';
@@ -1423,6 +1381,13 @@ $str.=$this->docBodyTagBegin().
                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='';
 
@@ -1482,15 +1447,21 @@ $str.=$this->docBodyTagBegin().
         * 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       boolean         If set, 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
+        * @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
-        * @return      string  JavaScript section for the HTML header.
+        * @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=FALSE,$foldout=FALSE,$newRowCharLimit=50,$noWrap=1,$fullWidth=FALSE)     {
+       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 = '';
 
                if (is_array($menuItems))       {
@@ -1499,7 +1470,7 @@ $str.=$this->docBodyTagBegin().
                        $options = array(array());
                        $divs = array();
                        $JSinit = array();
-                       $id = 'DTM-'.t3lib_div::shortMD5($identString);
+                       $id = $this->getDynTabMenuId($identString);
                        $noWrap = $noWrap ? ' nowrap="nowrap"' : '';
 
                                // Traverse menu items
@@ -1507,61 +1478,73 @@ $str.=$this->docBodyTagBegin().
                        $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)       {       // 50 characters is probably a reasonable count of characters before switching to next row of tabs.
+                               if (!$foldout && ($titleLenCount>$newRowCharLimit | ($def['newline'] === true && $titleLenCount > 0))) {
                                        $titleLenCount=0;
                                        $tabRows++;
                                        $options[$tabRows] = array();
                                }
 
-                               if ($toggle)    {
+                               if ($toggle==1) {
                                        $onclick = 'this.blur(); DTM_toggle("'.$id.'","'.$index.'"); return false;';
                                } else {
-                                       $onclick = 'this.blur(); DTM_activate("'.$id.'","'.$index.'"); return false;';
+                                       $onclick = 'this.blur(); DTM_activate("'.$id.'","'.$index.'", '.($toggle<0?1:0).'); return false;';
                                }
 
-                               $isActive = strcmp($def['content'],'');
+                               $isEmpty = !(strcmp(trim($def['content']),'') || strcmp(trim($def['icon']),''));
+
+                               // "Removes" empty tabs
+                               if ($isEmpty && $dividers2tabs == 1) {
+                                       continue;
+                               }
+
+                               $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="'.($isActive ? 'tab' : 'disabled').'" id="'.$id.'-'.$index.'-MENU"'.$noWrap.'>'.
-                                                       ($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
+                                                       <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;').
-                                                       ($isActive ? '</a>' :'').
+                                                       ($isEmpty ? '' : '</a>').
                                                        '</td>';
                                        $titleLenCount+= strlen($def['label']);
                                } else {
                                                // Create DIV layer for content:
                                        $divs[] = '
-                                               <div class="'.($isActive ? 'tab' : 'disabled').'" id="'.$id.'-'.$index.'-MENU">'.
-                                                       ($isActive ? '<a href="#" onclick="'.htmlspecialchars($onclick).'"'.($def['linkTitle'] ? ' title="'.htmlspecialchars($def['linkTitle']).'"':'').'>' : '').
+                                               <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;').
-                                                       ($isActive ? '</a>' : '').
+                                                       $requiredIcon.
+                                                       ($isEmpty ? '' : '</a>').
                                                        '</div>';
                                }
 
-                               if ($isActive)  {
-                                               // 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:
+                                       // 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[] = '
-                                                       DTM_array["'.$id.'"]['.$c.'] = "'.$id.'-'.$index.'";
+                                               if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'",1); }
                                        ';
-                                       if ($toggle)    {
-                                               $JSinit[] = '
-                                                       if (top.DTM_currentTabs["'.$id.'-'.$index.'"]) { DTM_toggle("'.$id.'","'.$index.'"); }
-                                               ';
-                                       }
-
-                                       $c++;
                                }
+
+                               $c++;
                        }
 
                                // Render menu:
@@ -1595,8 +1578,7 @@ $str.=$this->docBodyTagBegin().
                                <script type="text/javascript">
                                        DTM_array["'.$id.'"] = new Array();
                                        '.implode('',$JSinit).'
-
-                                       '.(!$toggle ? 'DTM_activate("'.$id.'",top.DTM_currentTabs["'.$id.'"]?top.DTM_currentTabs["'.$id.'"]:0);' : '').'
+                                       '.($toggle<=0 ? 'DTM_activate("'.$id.'", top.DTM_currentTabs["'.$id.'"]?top.DTM_currentTabs["'.$id.'"]:'.intval($defaultTabIndex).', 0);' : '').'
                                </script>
 
                                ';
@@ -1607,53 +1589,28 @@ $str.=$this->docBodyTagBegin().
        }
 
        /**
+        * 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      string          JavaScript section for the HTML header. (return value is deprecated since TYPO3 4.3, will be removed in TYPO3 4.5)
         */
        function getDynTabMenuJScode()  {
-               return '
-                       <script type="text/javascript">
-                       /*<![CDATA[*/
-                               var DTM_array = new Array();
-
-                               function DTM_activate(idBase,index)     {       //
-                                               // Hiding all:
-                                       if (DTM_array[idBase])  {
-                                               for(cnt = 0; cnt < DTM_array[idBase].length ; cnt++)    {
-                                                       if (DTM_array[idBase][cnt] != idBase+"-"+index) {
-                                                               document.getElementById(DTM_array[idBase][cnt]+"-DIV").style.display = "none";
-                                                               document.getElementById(DTM_array[idBase][cnt]+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
-                                                       }
-                                               }
-                                       }
-
-                                               // Showing one:
-                                       if (document.getElementById(idBase+"-"+index+"-DIV"))   {
-                                               document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
-                                               document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tabact";
-
-                                                       // Setting current tab index in top of browser.
-                                               top.DTM_currentTabs[idBase] = index;
-                                       }
-                               }
-                               function DTM_toggle(idBase,index)       {       //
-                                               // Showing one:
-                                       if (document.getElementById(idBase+"-"+index+"-DIV"))   {
-                                               if (document.getElementById(idBase+"-"+index+"-DIV").style.display == "block")  {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "none";
-                                                       document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tab";
-                                                       top.DTM_currentTabs[idBase+"-"+index] = 0;
-                                               } else {
-                                                       document.getElementById(idBase+"-"+index+"-DIV").style.display = "block";
-                                                       document.getElementById(idBase+"-"+index+"-MENU").attributes.getNamedItem("class").nodeValue = "tabact";
-                                                       top.DTM_currentTabs[idBase+"-"+index] = 1;
-                                               }
-                                       }
-                               }
-                       /*]]>*/
-                       </script>
-               ';
+               $this->loadJavascriptLib('js/tabmenu.js');
+               // return value deprecated since TYPO3 4.3
+               return '';
        }
 
        /**
@@ -1666,64 +1623,310 @@ $str.=$this->docBodyTagBegin().
         */
        function getVersionSelector($id,$noAction=FALSE)        {
 
-               if ($id>0 && t3lib_extMgm::isLoaded('version')) {
+               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>';
 
-                               // 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_id');
+                                               // Create onchange handler:
+                                       $onChange = "window.location.href=this.options[this.selectedIndex].value;";
 
-                               // If more than one was found...:
-                       if (count($versions)>1) {
+                                               // 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>';
+                                       }
 
-                                       // 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'].']'.($vRow['uid']==$onlineId ? ' =>'.$GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:ver.online').'<=':'')).
-                                                       '</option>';
+                                               // 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) {
 
-                                       // 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>';
+                                       // 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;
+                               }
 
-                                       // Create onchange handler:
-                               $onChange = "document.location=this.options[this.selectedIndex].value;";
+                               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>
+                                               ';
+                                       }
+                               }
+                       }
+               }
+       }
 
-                                       // 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&cmd[pages]['.$onlineId.'][version][swapContent]=1',t3lib_div::linkThisScript(array('id'=>$onlineId))).'">'.
-                                                       '<img'.t3lib_iconWorks::skinImg($this->backPath,'gfx/insert2.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>';
+
+       /**
+        * 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, '###|###');
 
-                                       // 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>
-                               ';
+       /**
+        * 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;
+       }
+}
 
 
 // ******************************
@@ -1770,25 +1973,15 @@ class mediumDoc extends template {
 }
 
 
-
-// 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']);
 }
 
 
 
-// ******************************************************
-// 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
 // ******************************
-$TBE_TEMPLATE = t3lib_div::makeInstance('template');
-?>
\ No newline at end of file
+$GLOBALS['TBE_TEMPLATE'] = t3lib_div::makeInstance('template');
+
+?>