Fixed bug #14717: [Usability] Add delay to close the context menu
[Packages/TYPO3.CMS.git] / typo3 / backend.php
index c89afcb..1d7f410 100644 (file)
@@ -2,7 +2,7 @@
 /***************************************************************
 *  Copyright notice
 *
-*  (c) 2007 Ingo Renner <ingo@typo3.org>
+*  (c) 2007-2010 Ingo Renner <ingo@typo3.org>
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
 
-require_once ('init.php');
-require_once ('template.php');
-require_once ('interfaces/interface.backend_toolbaritem.php');
+require_once('init.php');
+require_once('template.php');
+require_once('interfaces/interface.backend_toolbaritem.php');
 
-require ('classes/class.typo3logo.php');
-require ('classes/class.modulemenu.php');
-require ('classes/class.workspaceselector.php');
+require('classes/class.typo3logo.php');
+require('classes/class.modulemenu.php');
+require_once('classes/class.donatewindow.php');
 
-require_once (PATH_t3lib.'class.t3lib_loadmodules.php');
-require_once (PATH_t3lib.'class.t3lib_basicfilefunc.php');
-require_once ('class.alt_menu_functions.inc');
+       // core toolbar items
+require('classes/class.workspaceselector.php');
+require('classes/class.clearcachemenu.php');
+require('classes/class.shortcutmenu.php');
+require('classes/class.backendsearchmenu.php');
+
+require_once('class.alt_menu_functions.inc');
 $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
 
 
@@ -48,29 +52,36 @@ $GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
  */
 class TYPO3backend {
 
-       private $content;
-       private $cssFiles;
-       private $js;
-       private $jsFiles;
+       protected $content;
+       protected $css;
+       protected $cssFiles;
+       protected $js;
+       protected $jsFiles;
+       protected $jsFilesAfterInline;
+       protected $toolbarItems;
+       private   $menuWidthDefault = 190; // intentionally private as nobody should modify defaults
+       protected $menuWidth;
 
        /**
         * Object for loading backend modules
         *
         * @var t3lib_loadModules
         */
-       private $moduleLoader;
+       protected $moduleLoader;
 
        /**
         * module menu generating object
         *
         * @var ModuleMenu
         */
-       private $moduleMenu;
+       protected $moduleMenu;
 
-       private $leftMenuWidth;
-       private $topHeight;
-       private $selectMenu;
-       private $toolbarItems;
+       /**
+        * Pagerenderer
+        *
+        * @var t3lib_PageRenderer
+        */
+       protected $pageRenderer;
 
        /**
         * constructor
@@ -78,41 +89,67 @@ class TYPO3backend {
         * @return      void
         */
        public function __construct() {
+
                        // Initializes the backend modules structure for use later.
                $this->moduleLoader = t3lib_div::makeInstance('t3lib_loadModules');
                $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
 
                $this->moduleMenu = t3lib_div::makeInstance('ModuleMenu');
 
-                       // Check for distances defined in the styles array:
-               if ($TBE_STYLES['dims']['leftMenuFrameW']) {
-                       $this->leftMenuWidth = $TBE_STYLES['dims']['leftMenuFrameW'];
-               }
-               if ($TBE_STYLES['dims']['topFrameH']) {
-                       $this->topHeight = $TBE_STYLES['dims']['topFrameH'];
-               }
-               if ($TBE_STYLES['dims']['selMenuFrame']) {
-                       $this->selectMenu = $TBE_STYLES['dims']['selMenuFrame'];
-               }
+               $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
+               $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
+               $this->pageRenderer->loadExtJS();
+
+                       // register the extDirect API providers
+                       // Note: we need to iterate thru the object, because the addProvider method
+                       // does this only with multiple arguments
+               $this->pageRenderer->addExtOnReadyCode(
+                       'for (var api in Ext.app.ExtDirectAPI) {
+                               Ext.Direct.addProvider(Ext.app.ExtDirectAPI[api]);
+                       }
+                       TYPO3.Backend = new TYPO3.Viewport(TYPO3.Viewport.configuration);
+                       ',
+                       TRUE
+               );
+
 
                        // add default BE javascript
-               $this->js = '';
+               $this->js      = '';
                $this->jsFiles = array(
-                       'contrib/prototype/prototype.js',
+                       'contrib/swfupload/swfupload.js',
+                       'contrib/swfupload/plugins/swfupload.swfobject.js',
+                       'contrib/swfupload/plugins/swfupload.cookies.js',
+                       'contrib/swfupload/plugins/swfupload.queue.js',
                        'md5.js',
-                       'js/sizemanager.js',
-                       '../t3lib/jsfunc.evalfield.js'
+                       'js/common.js',
+                       'js/extjs/backendsizemanager.js',
+                       'js/toolbarmanager.js',
+                       'js/modulemenu.js',
+                       'js/iecompatibility.js',
+                       'js/flashupload.js',
+                       '../t3lib/jsfunc.evalfield.js',
+                       '../t3lib/js/extjs/ux/flashmessages.js',
+                       '../t3lib/js/extjs/ux/ext.ux.tabclosemenu.js',
+                       'js/backend.js',
+                       'js/loginrefresh.js',
+                       'js/extjs/debugPanel.js',
+                       'js/extjs/viewport.js',
+                       'js/extjs/viewportConfiguration.js',
                );
 
                        // add default BE css
-               $this->cssFiles = array(
-                       'css/backend-scaffolding.css',
-                       'css/backend-style.css',
-                       'css/verticalmenu.css'
-               );
+               $this->css      = '';
+               $this->cssFiles = array();
 
                $this->toolbarItems = array();
                $this->initializeCoreToolbarItems();
+
+               $this->menuWidth = $this->menuWidthDefault;
+               if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int) $this->menuWidth) {
+                       $this->menuWidth = (int) $GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'];
+               }
+
+               $this->executeHook('constructPostProcess');
        }
 
        /**
@@ -120,26 +157,27 @@ class TYPO3backend {
         *
         * @return      void
         */
-       private function initializeCoreToolbarItems() {
+       protected function initializeCoreToolbarItems() {
 
                $coreToolbarItems = array(
                        'workspaceSelector' => 'WorkspaceSelector',
-                       /* TODO
-                       'clearCacheActions' => '',
-                       'backendSearch'     => '',
-                       'shortcutMenu'      => ''
-                       */
+                       'shortcuts'         => 'ShortcutMenu',
+                       'clearCacheActions' => 'ClearCacheMenu',
+                       'backendSearch'     => 'BackendSearchMenu'
                );
 
-               foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClass) {
-                       $toolbarItem = t3lib_div::makeInstance($toolbarItemClass);
+               foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
+                       $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
 
                        if(!($toolbarItem instanceof backend_toolbarItem)) {
                                throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195126772);
                        }
 
-                       $toolbarItem->setBackend($this);
-                       $this->toolbarItems[] = $toolbarItem;
+                       if($toolbarItem->checkAccess()) {
+                               $this->toolbarItems[$toolbarItemName] = $toolbarItem;
+                       } else {
+                               unset($toolbarItem);
+                       }
                }
        }
 
@@ -149,76 +187,98 @@ class TYPO3backend {
         * @return      void
         */
        public function render()        {
+               $this->executeHook('renderPreProcess');
+
+               if (t3lib_div::makeInstance('DonateWindow')->isDonateWindowAllowed()) {
+                       $this->pageRenderer->addJsFile('js/donate.js');
+               }
 
-                       // prepare the scaffolding, at this point extension still may addjavascript and css
+                       // prepare the scaffolding, at this point extension may still add javascript and css
                $logo         = t3lib_div::makeInstance('TYPO3Logo');
                $logo->setLogo('gfx/typo3logo_mini.png');
 
                $menu         = $this->moduleMenu->render();
-               $cacheActions = $this->moduleMenu->renderCacheActions();
-               $logout       = $this->moduleMenu->renderLogoutButton();
-               $loginInfo    = $this->getLoggedInUserLabel();
+
+               if ($this->menuWidth != $this->menuWidthDefault) {
+                       $this->css .= '
+                               #typo3-top {
+                                       margin-left: ' . $this->menuWidth . 'px;
+                               }
+                       ';
+               }
 
                        // create backend scaffolding
                $backendScaffolding = '
        <div id="typo3-backend">
-               <div id="typo3-top-container">
+               <div id="typo3-top-container" class="x-hide-display">
                        <div id="typo3-logo">'.$logo->render().'</div>
-                       <div id="typo3-top" class="typo3-top-toolbar">'
-                               .$this->renderToolbar()
-                       .'</div>
+                       <div id="typo3-top" class="typo3-top-toolbar">' .
+                               $this->renderToolbar() .
+                       '</div>
                </div>
                <div id="typo3-main-container">
-                       <div id="typo3-side-menu">'
-                               .$menu
-                               .$cacheActions
-                               .$logout
-                               .$loginInfo
-                               .'
-                       </div>
-                       <div id="typo3-content">
-                               <iframe src="alt_intro.php" name="content" id="content" marginwidth="0" marginheight="0" frameborder="0"  scrolling="auto" noresize="noresize"></iframe>
+                       <div id="typo3-side-menu" class="x-hide-display">' .
+                               $menu .
+                       '</div>
+                       <div id="typo3-content" class="x-hide-display">
+                               <iframe src="alt_intro.php" name="content" id="content" marginwidth="0" marginheight="0" frameborder="0" scrolling="auto"></iframe>
                        </div>
                </div>
        </div>
-</body>
-</html>';
+';
 
                /******************************************************
                 * now put the complete backend document together
                 ******************************************************/
 
-                       // set doctype
-               $GLOBALS['TBE_TEMPLATE']->docType = 'xhtml_trans';
+               foreach($this->cssFiles as $cssFileName => $cssFile) {
+                       $this->pageRenderer->addCssFile($cssFile);
 
-                       // add javascript
-               foreach($this->jsFiles as $jsFile) {
-                       $GLOBALS['TBE_TEMPLATE']->JScode .= '
-                       <script type="text/javascript" src="'.$jsFile.'"></script>';
+                               // load addditional css files to overwrite existing core styles
+                       if(!empty($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName])) {
+                               $this->pageRenderer->addCssFile($GLOBALS['TBE_STYLES']['stylesheets'][$cssFileName]);
+                       }
                }
-               $GLOBALS['TBE_TEMPLATE']->JScode .= chr(10);
-               $this->generateJavascript();
-               $GLOBALS['TBE_TEMPLATE']->JScode .= $GLOBALS['TBE_TEMPLATE']->wrapScriptTags($this->js);
 
-                       // abusing the JS container to add CSS
-                       // TODO fix template.php
-               foreach($this->cssFiles as $cssFile) {
-                       $GLOBALS['TBE_TEMPLATE']->JScode .= '
-                       <link rel="stylesheet" type="text/css" href="'.$cssFile.'" />
-                       ';
+               if(!empty($this->css)) {
+                       $this->pageRenderer->addCssInlineBlock('BackendInlineCSS', $this->css);
+               }
+
+               foreach ($this->jsFiles as $jsFile) {
+                       $this->pageRenderer->addJsFile($jsFile);
                }
-               // TODO add CSS from $this->css
 
-                       // set document title
-               $title = $TYPO3_CONF_VARS['SYS']['sitename'] ?
-                                       $TYPO3_CONF_VARS['SYS']['sitename'].' [TYPO3 '.TYPO3_version.']'
-                               :       'TYPO3 '.TYPO3_version;
+                       // Those lines can be removed once we have at least one official ExtDirect router within the backend.
+               $hasExtDirectRouter = FALSE;
+               if (isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect']) && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'])) {
+                       foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ExtDirect'] as $key => $value) {
+                               if (strpos($key, 'TYPO3.Backend') !== FALSE) {
+                                       $hasExtDirectRouter = TRUE;
+                                       break;
+                               }
+                       }
+               }
+               if ($hasExtDirectRouter) {
+                       $this->pageRenderer->addJsFile('ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.Backend', NULL, FALSE);
+               }
+
+               $this->generateJavascript();
+               $this->pageRenderer->addJsInlineCode('BackendInlineJavascript', $this->js);
+
+
+                       // set document title:
+               $title = ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']
+                       ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'].' [TYPO3 '.TYPO3_version.']'
+                       : 'TYPO3 '.TYPO3_version
+               );
 
                        // start page header:
                $this->content .= $GLOBALS['TBE_TEMPLATE']->startPage($title);
+               $this->content .= $backendScaffolding;
                $this->content .= $GLOBALS['TBE_TEMPLATE']->endPage();
 
-               $this->content .= $backendScaffolding;
+               $hookConfiguration = array('content' => &$this->content);
+               $this->executeHook('renderPostProcess', $hookConfiguration);
 
                echo $this->content;
        }
@@ -228,30 +288,59 @@ class TYPO3backend {
         *
         * @return      string  top toolbar elements as HTML
         */
-       private function renderToolbar() {
-               $toolbar = '';
+       protected function renderToolbar() {
+
+                       // move search to last position
+               $search = $this->toolbarItems['backendSearch'];
+               unset($this->toolbarItems['backendSearch']);
+               $this->toolbarItems['backendSearch'] = $search;
+
+               $toolbar = '<ul id="typo3-toolbar">';
+               $toolbar.= '<li>'.$this->getLoggedInUserLabel().'</li>
+                                       <li><div id="logout-button" class="toolbar-item no-separator">'.$this->moduleMenu->renderLogoutButton().'</div></li>';
 
                foreach($this->toolbarItems as $toolbarItem) {
-                       $toolbar .= $toolbarItem->render();
+                       $menu = $toolbarItem->render();
+                       if ($menu) {
+                               $additionalAttributes = $toolbarItem->getAdditionalAttributes();
+                               $toolbar .= '<li' . $additionalAttributes . '>' .$menu. '</li>';
+                       }
                }
 
-               return $toolbar;
+               return $toolbar.'</ul>';
        }
 
        /**
-        * gets the label of the currently loged in BE user
+        * Gets the label of the BE user currently logged in
         *
         * @return      string          html code snippet displaying the currently logged in user
         */
-       private function getLoggedInUserLabel() {
-               $username = '<p id="username">['.htmlspecialchars($GLOBALS['BE_USER']->user['username']).']</p>';;
+       protected function getLoggedInUserLabel() {
+               global $BE_USER, $BACK_PATH;
+
+                $icon = t3lib_iconWorks::getSpriteIcon('status-user-'. ($BE_USER->isAdmin() ? 'admin' : 'backend'));
+
+               $label = $GLOBALS['BE_USER']->user['realName'] ?
+                       $BE_USER->user['realName'] . ' (' . $BE_USER->user['username'] . ')' :
+                       $BE_USER->user['username'];
+
+                       // Link to user setup if it's loaded and user has access
+               $link = '';
+               if (t3lib_extMgm::isLoaded('setup') && $BE_USER->check('modules','user_setup')) {
+                       $link = '<a href="#" onclick="top.goToModule(\'user_setup\');this.blur();return false;">';
+               }
+
+               $username = '">'.$link.$icon.'<span>'.htmlspecialchars($label).'</span>'.($link?'</a>':'');
 
                        // superuser mode
                if($BE_USER->user['ses_backuserid']) {
-                       $username = '<p id="username" class="typo3-red-background">[SU: '.htmlspecialchars($GLOBALS['BE_USER']->user['username']).']</p>';
+                       $username   = ' su-user">'.$icon.
+                       '<span title="' . $GLOBALS['LANG']->getLL('switchtouser') . '">' .
+                       $GLOBALS['LANG']->getLL('switchtousershort') . ' </span>' .
+                       '<span>' . htmlspecialchars($label) . '</span>';
                }
 
-               return '<div id="login-info">'.$username.'</div>';
+               return '<div id="username" class="toolbar-item no-separator'.$username.'</div>';
        }
 
        /**
@@ -259,11 +348,11 @@ class TYPO3backend {
         *
         * @return      void
         */
-       private function generateJavascript() {
+       protected function generateJavascript() {
 
                $pathTYPO3          = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
                $goToModuleSwitch   = $this->moduleMenu->getGotoModuleJavascript();
-               $moduleFramesHelper = implode(chr(10), $this->moduleMenu->getFsMod());
+               $moduleFramesHelper = implode(LF, $this->moduleMenu->getFsMod());
 
                        // If another page module was specified, replace the default Page module with the new one
                $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
@@ -274,222 +363,122 @@ class TYPO3backend {
                        $menuFrameName = 'topmenuFrame';
                }
 
-               $this->js .= '
-       /**
-        * Function similar to PHPs  rawurlencode();
-        */
-       function rawurlencode(str)      {       //
-               var output = escape(str);
-               output = str_replace("*","%2A", output);
-               output = str_replace("+","%2B", output);
-               output = str_replace("/","%2F", output);
-               output = str_replace("@","%40", output);
-               return output;
-       }
-
-       /**
-        * String-replace function
-        */
-       function str_replace(match,replace,string)      {       //
-               var input = ""+string;
-               var matchStr = ""+match;
-               if (!matchStr)  {return string;}
-               var output = "";
-               var pointer=0;
-               var pos = input.indexOf(matchStr);
-               while (pos!=-1) {
-                       output+=""+input.substr(pointer, pos-pointer)+replace;
-                       pointer=pos+matchStr.length;
-                       pos = input.indexOf(match,pos+1);
-               }
-               output+=""+input.substr(pointer);
-               return output;
-       }
-
-       /**
-        * TypoSetup object.
-        */
-       function typoSetup()    {       //
-               this.PATH_typo3 = "'.$pathTYPO3.'";
-               this.PATH_typo3_enc = "'.rawurlencode($pathTYPO3).'";
-               this.username = "'.$GLOBALS['BE_USER']->user['username'].'";
-               this.uniqueID = "'.t3lib_div::shortMD5(uniqid('')).'";
-               this.navFrameWidth = 0;
-       }
-       var TS = new typoSetup();
-
-       /**
-        * Functions for session-expiry detection:
-        */
-       function busy() {       //
-               this.loginRefreshed = busy_loginRefreshed;
-               this.checkLoginTimeout = busy_checkLoginTimeout;
-               this.openRefreshWindow = busy_OpenRefreshWindow;
-               this.busyloadTime=0;
-               this.openRefreshW=0;
-               this.reloginCancelled=0;
-       }
-       function busy_loginRefreshed()  {       //
-               var date = new Date();
-               this.busyloadTime = Math.floor(date.getTime()/1000);
-               this.openRefreshW=0;
-       }
-       function busy_checkLoginTimeout()       {       //
-               var date = new Date();
-               var theTime = Math.floor(date.getTime()/1000);
-               if (theTime > this.busyloadTime+'.intval($GLOBALS['BE_USER']->auth_timeout_field).'-30) {
-                       return true;
-               }
-       }
-       function busy_OpenRefreshWindow()       {       //
-               vHWin=window.open("login_frameset.php","relogin_"+TS.uniqueID,"height=350,width=700,status=0,menubar=0,location=1");
-               vHWin.focus();
-               this.openRefreshW=1;
-       }
-       function busy_checkLoginTimeout_timer() {       //
-               if (busy.checkLoginTimeout() && !busy.reloginCancelled && !busy.openRefreshW)   {
-                       if (confirm('.$GLOBALS['LANG']->JScharCode($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.refresh_login')).'))      {
-                               busy.openRefreshWindow();
-                       } else  {
-                               busy.reloginCancelled = 1;
-                       }
-               }
-               window.setTimeout("busy_checkLoginTimeout_timer();",2*1000);    // Each 2nd second is enough for checking. The popup will be triggered 10 seconds before the login expires (see above, busy_checkLoginTimeout())
-
-                       // Detecting the frameset module navigation frame widths (do this AFTER setting new timeout so that any errors in the code below does not prevent another time to be set!)
-               if (top && top.content && top.content.nav_frame && top.content.nav_frame.document && top.content.nav_frame.document.body)       {
-                       TS.navFrameWidth = (top.content.nav_frame.document.documentElement && top.content.nav_frame.document.documentElement.clientWidth) ? top.content.nav_frame.document.documentElement.clientWidth : top.content.nav_frame.document.body.clientWidth;
-               }
-       }
-
-       /**
-        * Launcing information window for records/files (fileref as "table" argument)
-        */
-       function launchView(table,uid,bP)       {       //
-               var backPath= bP ? bP : "";
-               var thePreviewWindow="";
-               thePreviewWindow = window.open(TS.PATH_typo3+"show_item.php?table="+encodeURIComponent(table)+"&uid="+encodeURIComponent(uid),"ShowItem"+TS.uniqueID,"height=400,width=550,status=0,menubar=0,resizable=0,location=0,directories=0,scrollbars=1,toolbar=0");
-               if (thePreviewWindow && thePreviewWindow.focus) {
-                       thePreviewWindow.focus();
-               }
-       }
-
-       /**
-        * Opens plain window with url
-        */
-       function openUrlInWindow(url,windowName)        {       //
-               regularWindow = window.open(url,windowName,"status=1,menubar=1,resizable=1,location=1,directories=0,scrollbars=1,toolbar=1");
-               regularWindow.focus();
-               return false;
-       }
-
-       /**
-        * Loads a URL in the topmenuFrame
-        */
-       function loadTopMenu(url)       {       //
-               top.topmenuFrame.location = url;
-       }
-
-       /**
-        * Loads a page id for editing in the page edit module:
-        */
-       function loadEditId(id,addGetVars)      {       //
-               top.fsMod.recentIds["web"]=id;
-               top.fsMod.navFrameHighlightedID["web"]="pages"+id+"_0";         // For highlighting
-
-               if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav)  {
-                       top.content.nav_frame.refresh_nav();
-               }
-
-               top.goToModule("'.$pageModule.'", 0, addGetVars?addGetVars:"");
-       }
-
-       /**
-        * Returns incoming URL (to a module) unless nextLoadModuleUrl is set. If that is the case nextLoadModuleUrl is returned (and cleared)
-        * Used by the shortcut frame to set a "intermediate URL"
-        */
-       var nextLoadModuleUrl="";
-       function getModuleUrl(inUrl)    {       //
-               var nMU;
-               if (top.nextLoadModuleUrl)      {
-                       nMU=top.nextLoadModuleUrl;
-                       top.nextLoadModuleUrl="";
-                       return nMU;
+               // determine security level from conf vars and default to super challenged
+               if ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) {
+                       $this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
                } else {
-                       return inUrl;
+                       $this->loginSecurityLevel = 'superchallenged';
                }
-       }
-
-       /**
-        * Print properties of an object
-        */
-       function debugObj(obj,name)     {       //
-               var acc;
-               for (i in obj) {
-                       if (obj[i])     {
-                               acc+=i+":  "+obj[i]+"\n";
-                       }
-               }
-               alert("Object: "+name+"\n\n"+acc);
-       }
-
-       /**
-        * Initialize login expiration warning object
-        */
-       var busy = new busy();
-       busy.loginRefreshed();
-       busy_checkLoginTimeout_timer();
 
+               $t3Configuration = array(
+                       'siteUrl' => t3lib_div::getIndpEnv('TYPO3_SITE_URL'),
+                       'PATH_typo3' => $pathTYPO3,
+                       'PATH_typo3_enc' => rawurlencode($pathTYPO3),
+                       'username' => htmlspecialchars($GLOBALS['BE_USER']->user['username']),
+                       'uniqueID' => t3lib_div::shortMD5(uniqid('')),
+                       'securityLevel' => $this->loginSecurityLevel,
+                       'TYPO3_mainDir' => TYPO3_mainDir,
+                       'pageModule' => $pageModule,
+                       'condensedMode' => $GLOBALS['BE_USER']->uc['condensedMode'] ? 1 : 0 ,
+                       'inWorkspace' => $GLOBALS['BE_USER']->workspace !== 0 ? 1 : 0,
+                       'workspaceFrontendPreviewEnabled' => $GLOBALS['BE_USER']->user['workspace_preview'] ? 1 : 0,
+                       'veriCode' => $GLOBALS['BE_USER']->veriCode(),
+                       'denyFileTypes' => PHP_EXTENSIONS_DEFAULT,
+                       'moduleMenuWidth' => $this->menuWidth - 1,
+                       'topBarHeight' => (int) $GLOBALS['TBE_STYLES']['dims']['topFrameH'],
+                       'showRefreshLoginPopup' => isset($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) ? intval($GLOBALS['TYPO3_CONF_VARS']['BE']['showRefreshLoginPopup']) : FALSE,
+               );
+               $t3LLLcore = array(
+                       'waitTitle' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_logging_in') ,
+                       'refresh_login_failed' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed'),
+                       'refresh_login_failed_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_failed_message'),
+                       'refresh_login_title' => sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_title'), htmlspecialchars($GLOBALS['BE_USER']->user['username'])),
+                       'login_expired' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_expired'),
+                       'refresh_login_username' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_username'),
+                       'refresh_login_password' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_password'),
+                       'refresh_login_emptyPassword' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_emptyPassword'),
+                       'refresh_login_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_button'),
+                       'refresh_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_logout_button'),
+                       'please_wait' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.please_wait'),
+                       'be_locked' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.be_locked'),
+                       'refresh_login_countdown_singular' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown_singular'),
+                       'refresh_login_countdown' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_countdown'),
+                       'login_about_to_expire' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire'),
+                       'login_about_to_expire_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.login_about_to_expire_title'),
+                       'refresh_login_refresh_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_login_refresh_button'),
+                       'refresh_direct_logout_button' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:mess.refresh_direct_logout_button'),
+                       'tabs_closeAll' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeAll'),
+                       'tabs_closeOther' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.closeOther'),
+                       'tabs_close' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tabs.close'),
+                       'donateWindow_title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.title'),
+                       'donateWindow_message' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.message'),
+                       'donateWindow_button_donate' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_donate'),
+                       'donateWindow_button_disable' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_disable'),
+                       'donateWindow_button_postpone' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:donateWindow.button_postpone'),
+               );
+               $t3LLLfileUpload = array(
+                       'windowTitle' => $GLOBALS['LANG']->getLL('fileUpload_windowTitle'),
+                       'buttonSelectFiles' => $GLOBALS['LANG']->getLL('fileUpload_buttonSelectFiles'),
+                       'buttonCancelAll' => $GLOBALS['LANG']->getLL('fileUpload_buttonCancelAll'),
+                       'infoComponentMaxFileSize' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentMaxFileSize'),
+                       'infoComponentFileUploadLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileUploadLimit'),
+                       'infoComponentFileTypeLimit' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentFileTypeLimit'),
+                       'infoComponentOverrideFiles' => $GLOBALS['LANG']->getLL('fileUpload_infoComponentOverrideFiles'),
+                       'processRunning' => $GLOBALS['LANG']->getLL('fileUpload_processRunning'),
+                       'uploadWait' => $GLOBALS['LANG']->getLL('fileUpload_uploadWait'),
+                       'uploadStarting' => $GLOBALS['LANG']->getLL('fileUpload_uploadStarting'),
+                       'uploadProgress' => $GLOBALS['LANG']->getLL('fileUpload_uploadProgress'),
+                       'uploadSuccess' => $GLOBALS['LANG']->getLL('fileUpload_uploadSuccess'),
+                       'errorQueueLimitExceeded' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueLimitExceeded'),
+                       'errorQueueFileSizeLimit' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueFileSizeLimit'),
+                       'errorQueueZeroByteFile' =>  $GLOBALS['LANG']->getLL('fileUpload_errorQueueZeroByteFile'),
+                       'errorQueueInvalidFiletype' => $GLOBALS['LANG']->getLL('fileUpload_errorQueueInvalidFiletype'),
+                       'errorUploadHttp' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadHttpError'),
+                       'errorUploadMissingUrl' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadMissingUrl'),
+                       'errorUploadIO' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadIO'),
+                       'errorUploadSecurityError' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadSecurityError'),
+                       'errorUploadLimit' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadLimit'),
+                       'errorUploadFailed' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFailed'),
+                       'errorUploadFileIDNotFound' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileIDNotFound'),
+                       'errorUploadFileValidation' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileValidation'),
+                       'errorUploadFileCancelled' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadFileCancelled'),
+                       'errorUploadStopped' => $GLOBALS['LANG']->getLL('fileUpload_errorUploadStopped'),
+                       'allErrorMessageTitle' => $GLOBALS['LANG']->getLL('fileUpload_allErrorMessageTitle'),
+                       'allErrorMessageText' => $GLOBALS['LANG']->getLL('fileUpload_allErrorMessageText'),
+                       'allError401' => $GLOBALS['LANG']->getLL('fileUpload_allError401'),
+                       'allError2038' => $GLOBALS['LANG']->getLL('fileUpload_allError2038'),
+               );
 
-       /**
-        * Highlight module:
-        */
-       var currentlyHighLightedId = "";
-       var currentlyHighLighted_restoreValue = "";
-       var currentlyHighLightedMain = "";
-       function highlightModuleMenuItem(trId, mainModule)      {       //
-               currentlyHighLightedMain = mainModule;
-                       // Get document object:
-               if (top.menu && top.menu.document)      {
-                       var docObj = top.menu.document;
-                       var HLclass = mainModule ? "c-mainitem-HL" : "c-subitem-row-HL";
-               } else if (top.topmenuFrame && top.topmenuFrame.document)       {
-                       var docObj = top.topmenuFrame.document;
-                       var HLclass = mainModule ? "c-mainitem-HL" : "c-subitem-HL";
+                       // Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
+               if ($GLOBALS['LANG']->charSet !== 'utf-8') {
+                       $t3Configuration['username'] = $GLOBALS['LANG']->csConvObj->conv($t3Configuration['username'], $GLOBALS['LANG']->charSet, 'utf-8');
+                       $GLOBALS['LANG']->csConvObj->convArray($t3LLLcore, $GLOBALS['LANG']->charSet, 'utf-8');
+                       $GLOBALS['LANG']->csConvObj->convArray($t3LLLfileUpload, $GLOBALS['LANG']->charSet, 'utf-8');
                }
 
-               if (docObj)     {
-                               // Reset old:
-                       if (currentlyHighLightedId && docObj.getElementById(currentlyHighLightedId))    {
-                               docObj.getElementById(currentlyHighLightedId).attributes.getNamedItem("class").nodeValue = currentlyHighLighted_restoreValue;
-                       }
-                               // Set new:
-                       currentlyHighLightedId = trId;
-                       if (currentlyHighLightedId && docObj.getElementById(currentlyHighLightedId))    {
-                               var classAttribObject = docObj.getElementById(currentlyHighLightedId).attributes.getNamedItem("class");
-                               currentlyHighLighted_restoreValue = classAttribObject.nodeValue;
-                               classAttribObject.nodeValue = HLclass;
-                       }
-               }
-       }
+               $this->js .= '
+       TYPO3.configuration = ' . json_encode($t3Configuration) . ';
+       TYPO3.LLL = {
+               core : ' . json_encode($t3LLLcore) . ',
+               fileUpload: ' . json_encode($t3LLLfileUpload) . '
+       };
 
        /**
-        * Function restoring previous selection in left menu after clearing cache
+        * TypoSetup object.
         */
-       function restoreHighlightedModuleMenuItem() {   //
-               if (currentlyHighLightedId) {
-                       highlightModuleMenuItem(currentlyHighLightedId,currentlyHighLightedMain);
-               }
+       function typoSetup()    {       //
+               this.PATH_typo3 = TYPO3.configuration.PATH_typo3;
+               this.PATH_typo3_enc = TYPO3.configuration.PATH_typo3_enc;
+               this.username = TYPO3.configuration.username;
+               this.uniqueID = TYPO3.configuration.uniqueID;
+               this.navFrameWidth = 0;
+               this.securityLevel = TYPO3.configuration.securityLevel;
+               this.veriCode = TYPO3.configuration.veriCode;
+               this.denyFileTypes = TYPO3.configuration.denyFileTypes;
        }
+       var TS = new typoSetup();
 
-       '.$goToModuleSwitch.'
-
-       /**
-        * reloads the menu frame
-        */
-       function refreshMenu() {
-               top.'.$menuFrameName.'.location.href = top.'.$menuFrameName.'.document.URL
-       }
+       var currentModuleLoaded = "";
 
        /**
         * Frameset Module object
@@ -505,30 +494,25 @@ class TYPO3backend {
                this.currentMainLoaded="";
                this.currentBank="0";
        }
-       var fsMod = new fsModules();
-       '.$moduleFramesHelper.'
-
-               // Used by Frameset Modules
-       var condensedMode = '.($GLOBALS['BE_USER']->uc['condensedMode']?1:0).';
-       var currentSubScript = "";
-       var currentSubNavScript = "";
+       var fsMod = new fsModules();' . $moduleFramesHelper . ';';
 
-               // Used for tab-panels:
-       var DTM_currentTabs = new Array();
-               ';
+                       // add goToModule code
+               $this->pageRenderer->addExtOnReadyCode('
+                       top.goToModule = ' . $goToModuleSwitch . ';
+               ');
 
                        // Check editing of page:
-               $this->editPageHandling();
+               $this->handlePageEditing();
                $this->setStartupModule();
        }
 
        /**
-        * Checking if the "&edit" variable was sent so we can open for editing the page.
+        * Checking if the "&edit" variable was sent so we can open it for editing the page.
         * Code based on code from "alt_shortcut.php"
         *
         * @return      void
         */
-       private function editPageHandling()     {
+       protected function handlePageEditing()  {
 
                if(!t3lib_extMgm::isLoaded('cms'))      {
                        return;
@@ -583,7 +567,7 @@ class TYPO3backend {
         *
         * @return      void
         */
-       private function setStartupModule() {
+       protected function setStartupModule() {
                $startModule = preg_replace('/[^[:alnum:]_]/', '', t3lib_div::_GET('module'));
 
                if(!$startModule)       {
@@ -596,18 +580,16 @@ class TYPO3backend {
 
                $moduleParameters = t3lib_div::_GET('modParams');
                if($startModule) {
-                       $this->js .= '
+                       $this->pageRenderer->addExtOnReadyCode('
                        // start in module:
-               function startInModule(modName, cMR_flag, addGetVars)   {       //
-                       if ($(content) && top.goToModule) {
+               function startInModule(modName, cMR_flag, addGetVars)   {
+                       Ext.onReady(function() {
                                top.goToModule(modName, cMR_flag, addGetVars);
-                       } else {
-                               window.setTimeout(function() { startInModuleModule(modName, cMR_flag, addGetVars); }, 500);
-                       }
+                       });
                }
 
-//             startInModule(\''.$startModule.'\', false, \''.$moduleParameters.'\');
-                       '; //TODO get start module working
+               startInModule(\''.$startModule.'\', false, '.t3lib_div::quoteJSvalue($moduleParameters).');
+                       ');
                }
        }
 
@@ -616,7 +598,7 @@ class TYPO3backend {
         *
         * @return      string  HTML code snippet to display the TYPO3 logo
         */
-       private function getLogo() {
+       protected function getLogo() {
                $logo = '<a href="http://www.typo3.com/" target="_blank" onclick="'.$GLOBALS['TBE_TEMPLATE']->thisBlur().'">'.
                                '<img'.t3lib_iconWorks::skinImg('','gfx/alt_backend_logo.gif','width="117" height="32"').' title="TYPO3 Content Management Framework" alt="" />'.
                                '</a>';
@@ -653,19 +635,18 @@ class TYPO3backend {
         * adds a javscript file to the backend after it has been checked that it exists
         *
         * @param       string  javascript file reference
-        * @return      void
+        * @return      boolean true if the javascript file was successfully added, false otherwise
         */
        public function addJavascriptFile($javascriptFile) {
-               //TODO add more checks if neccessary
-
-               if(file_exists(t3lib_div::resolveBackPath(PATH_site.$javascriptFile))) {
-
-                       if(t3lib_div::isFirstPartOfStr($javascriptFile, 'typo3/')) {
-                               $javascriptFile = substr($javascriptFile, 6); // make relative to typo3/
-                       }
+               $jsFileAdded = false;
 
+                       //TODO add more checks if neccessary
+               if(file_exists(t3lib_div::resolveBackPath(PATH_typo3.$javascriptFile))) {
                        $this->jsFiles[] = $javascriptFile;
+                       $jsFileAdded     = true;
                }
+
+               return $jsFileAdded;
        }
 
        /**
@@ -685,47 +666,73 @@ class TYPO3backend {
        /**
         * adds a css file to the backend after it has been checked that it exists
         *
+        * @param       string  the css file's name with out the .css ending
         * @param       string  css file reference
-        * @return      void
+        * @return      boolean true if the css file was added, false otherwise
         */
-       public function addCssFile($cssFile) {
-               //TODO add more checks if neccessary
+       public function addCssFile($cssFileName, $cssFile) {
+               $cssFileAdded = false;
 
-               if(file_exists(t3lib_div::resolveBackPath(PATH_site.$cssFile))) {
+               if(empty($this->cssFiles[$cssFileName])) {
+                       $this->cssFiles[$cssFileName] = $cssFile;
+                       $cssFileAdded = true;
+               }
 
-                       if(t3lib_div::isFirstPartOfStr($cssFile, 'typo3/')) {
-                               $cssFile = substr($cssFile, 6); // make relative to typo3/
-                       }
+               return $cssFileAdded;
+       }
 
-                       $this->cssFiles[] = $cssFile;
+       /**
+        * adds an item to the toolbar, the class file for the toolbar item must be loaded at this point
+        *
+        * @param       string  toolbar item name, f.e. tx_toolbarExtension_coolItem
+        * @param       string  toolbar item class name, f.e. tx_toolbarExtension_coolItem
+        * @return      void
+        */
+       public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
+               $toolbarItem = t3lib_div::makeInstance($toolbarItemClassName, $this);
+
+               if(!($toolbarItem instanceof backend_toolbarItem)) {
+                       throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface backend_toolbarItem', 1195125501);
+               }
+
+               if($toolbarItem->checkAccess()) {
+                       $this->toolbarItems[$toolbarItemName] = $toolbarItem;
+               } else {
+                       unset($toolbarItem);
                }
        }
 
        /**
-        * adds an item to the toolbar
+        * Executes defined hooks functions for the given identifier.
+        *
+        * These hook identifiers are valid:
+        *      + constructPostProcess
+        *      + renderPreProcess
+        *      + renderPostProcess
         *
-        * @param       string  toolbar item class reference, f.e. EXT:toolbarextension/class.tx_toolbarextension_coolitem.php:tx_toolbarExtension_coolItem
+        * @param string $identifier Specific hook identifier
+        * @param array $hookConfiguration Additional configuration passed to hook functions
+        * @return void
         */
-       public function addToolbarItem($toolbarItemName, $toolbarItemClassReference) {
-               $toolbarItem = t3lib_div::getUserObj($toolbarItemClassReference);
+       protected function executeHook($identifier, array $hookConfiguration = array()) {
+               $options =& $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/backend.php'];
 
-               if(!($toolbarItem instanceof t3lib_backendToolbarItem)) {
-                       throw new UnexpectedValueException('$toolbarItem "'.$toolbarItemName.'" must implement interface t3lib_backendToolbarItem', 1195125501);
+               if(isset($options[$identifier]) && is_array($options[$identifier])) {
+                       foreach($options[$identifier] as $hookFunction) {
+                               t3lib_div::callUserFunction($hookFunction, $hookConfiguration, $this);
+                       }
                }
-
-               $toolbarItem->setBackend($this);
-               $this->toolbarItems[$toolbarItemName] = $toolbarItem;
        }
 }
 
 
        // include XCLASS
-if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php'])      {
+if(defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']) {
        include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/backend.php']);
 }
 
 
-// document generation
+       // document generation
 $TYPO3backend = t3lib_div::makeInstance('TYPO3backend');
 
        // include extensions which may add css, javascript or toolbar items
@@ -737,4 +744,4 @@ if(is_array($GLOBALS['TYPO3_CONF_VARS']['typo3/backend.php']['additionalBackendI
 
 $TYPO3backend->render();
 
-?>
\ No newline at end of file
+?>