Index: t3lib/class.t3lib_befunc.php =================================================================== --- t3lib/class.t3lib_befunc.php (revision 8834) +++ t3lib/class.t3lib_befunc.php (working copy) @@ -2933,8 +2933,8 @@ $signals[] = $params['JScode']; } else if ($set == 'updatePageTree' || $set == 'updateFolderTree') { $signals[] = ' - if (top && top.content && top.content.nav_frame && top.content.nav_frame.Tree) { - top.content.nav_frame.Tree.refresh(); + if (top && top.TYPO3.Backend.NavigationContainer) { + top.TYPO3.Backend.NavigationContainer.refresh(); }'; } } Index: t3lib/class.t3lib_loadmodules.php =================================================================== --- t3lib/class.t3lib_loadmodules.php (revision 8834) +++ t3lib/class.t3lib_loadmodules.php (working copy) @@ -454,7 +454,7 @@ for($i=0;$i < $slashes;$i++) { $destDir = '../'.$destDir; } - return $destDir; + return t3lib_div::resolveBackPath($destDir); } } Index: t3lib/config_default.php =================================================================== --- t3lib/config_default.php (revision 8834) +++ t3lib/config_default.php (working copy) @@ -281,7 +281,7 @@ 'ShortcutMenu::delete' => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->deleteAjaxShortcut', 'ShortcutMenu::create' => 'typo3/classes/class.shortcutmenu.php:ShortcutMenu->createAjaxShortcut', 'ModuleMenu::saveMenuState' => 'typo3/classes/class.modulemenu.php:ModuleMenu->saveMenuState', - 'ModuleMenu::render' => 'typo3/classes/class.modulemenu.php:ModuleMenu->renderAjax', + 'ModuleMenu::getData' => 'typo3/classes/class.modulemenu.php:ModuleMenu->getModuleData', 'BackendLogin::login' => 'typo3/classes/class.ajaxlogin.php:AjaxLogin->login', 'BackendLogin::logout' => 'typo3/classes/class.ajaxlogin.php:AjaxLogin->logout', 'BackendLogin::refreshLogin' => 'typo3/classes/class.ajaxlogin.php:AjaxLogin->refreshLogin', Index: typo3/alt_clickmenu.php =================================================================== --- typo3/alt_clickmenu.php (revision 8834) +++ typo3/alt_clickmenu.php (working copy) @@ -428,7 +428,7 @@ * @return string JavaScript for an onClick event. */ function urlRefForCM($url,$retUrl='',$hideCM=1,$overrideLoc='') { - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick= ($overrideLoc ? 'var docRef='.$overrideLoc : 'var docRef=(top.content.list_frame)?top.content.list_frame:'.$loc).'; docRef.location.href=top.TS.PATH_typo3+\''.$url.'\''. ($retUrl ? "+'&" . $retUrl . "='+top.rawurlencode(" . $this->frameLocation('docRef.document') . ')' :'') . ';' . ($hideCM ? 'return hideCM();' : ''); @@ -475,7 +475,7 @@ */ function DB_paste($table,$uid,$type,$elInfo) { $editOnClick = ''; - $loc = 'top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; if($GLOBALS['BE_USER']->jsConfirmation(2)) { $conf = $loc.' && confirm('.$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.'.($elInfo[2]=='copy'?'copy':'move').'_'.$type),$elInfo[0],$elInfo[1])).')'; } else { @@ -534,7 +534,10 @@ * @internal */ function DB_perms($table,$uid,$rec) { - $url = 'mod/web/perm/index.php?id=' . $uid . ($rec['perms_userid'] == $GLOBALS['BE_USER']->user['uid'] || $GLOBALS['BE_USER']->isAdmin() ? '&return_id=' . $uid . '&edit=1' : ''); + if (!t3lib_extMgm::isLoaded('perm')) { + return ''; + } + $url = t3lib_extMgm::extRelPath('perm') . 'mod1/index.php?id=' . $uid . ($rec['perms_userid'] == $GLOBALS['BE_USER']->user['uid'] || $GLOBALS['BE_USER']->isAdmin() ? '&return_id=' . $uid . '&edit=1' : ''); return $this->linkItem( $GLOBALS['LANG']->makeEntities($GLOBALS['LANG']->getLL('CM_perms')), $this->excludeIcon(t3lib_iconWorks::getSpriteIcon('status-status-locked')), @@ -670,7 +673,7 @@ $pageModule = t3lib_BEfunc::isModuleSetInTBE_MODULES($newPageModule) ? $newPageModule : 'web_layout'; $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ? '.list_frame':''); + $loc = 'top.content.list_frame'; $addParam=''; $theIcon = 'actions-document-open'; if ( @@ -707,7 +710,7 @@ */ function DB_new($table,$uid) { $editOnClick=''; - $loc='top.content'.(!$this->alwaysContentFrame?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick='if('.$loc.'){'.$loc.".location.href=top.TS.PATH_typo3+'". ($this->listFrame? "alt_doc.php?returnUrl='+top.rawurlencode(" . $this->frameLocation($loc . '.document') . ")+'&edit[".$table."][-".$uid."]=new'": @@ -732,7 +735,7 @@ */ function DB_delete($table,$uid,$elInfo) { $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; if($GLOBALS['BE_USER']->jsConfirmation(4)) { $conf = "confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),$elInfo[0]) . t3lib_BEfunc::referenceCount($table,$uid,' (There are %s reference(s) to this record!)') . @@ -742,7 +745,7 @@ $conf = '1==1'; } $editOnClick = 'if(' . $loc . " && " . $conf . " ){" . $loc . ".location.href=top.TS.PATH_typo3+'tce_db.php?redirect='+top.rawurlencode(" . $this->frameLocation($loc . '.document') . ")+'". - "&cmd[".$table.']['.$uid.'][delete]=1&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}"; + "&cmd[".$table.']['.$uid.'][delete]=1&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode()."';}hideCM();top.nav.refresh();"; return $this->linkItem( $this->label('delete'), @@ -809,9 +812,10 @@ function DB_changeFlag($table, $rec, $flagField, $title, $name, $iconRelPath='gfx/') { $uid = $rec['_ORIG_uid'] ? $rec['_ORIG_uid'] : $rec['uid']; $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick = 'if(' . $loc . '){' . $loc . ".location.href=top.TS.PATH_typo3+'tce_db.php?redirect='+top.rawurlencode(" . $this->frameLocation($loc . '.document') . ")+'" . - "&data[".$table.']['.$uid.']['.$flagField.']='.($rec[$flagField]?0:1).'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}"; + "&data[" . $table . '][' . $uid . '][' . $flagField . ']=' . + ($rec[$flagField] ? 0 : 1) .'&prErr=1&vC=' . $GLOBALS['BE_USER']->veriCode()."';}hideCM();top.nav.refresh();"; return $this->linkItem( $title, @@ -923,14 +927,14 @@ * @internal */ function FILE_launch($path,$script,$type,$image,$noReturnUrl=FALSE) { - $loc='top.content'.(!$this->alwaysContentFrame?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick = 'if(' . $loc . '){' . $loc . ".location.href=top.TS.PATH_typo3+'".$script.'?target=' . rawurlencode($path) . ($noReturnUrl ? "'" : "&returnUrl='+top.rawurlencode(" . $this->frameLocation($loc . '.document') . ")") . ";}"; return $this->linkItem( $this->label($type), $this->excludeIcon('PH_backPath,'gfx/'.$image,'width="12" height="12"').' alt="" />'), - $editOnClick.'return hideCM();' + $editOnClick . 'top.nav.refresh();return hideCM();' ); } @@ -946,14 +950,14 @@ $type = 'upload'; $image = 'upload.gif'; if ($GLOBALS['BE_USER']->uc['enableFlashUploader']) { - $loc='top.content'.(!$this->alwaysContentFrame?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick = 'if (top.TYPO3.FileUploadWindow.isFlashAvailable()) { initFlashUploader("' . rawurlencode($path) . '"); } else if(' . $loc . '){' . $loc . ".location.href=top.TS.PATH_typo3+'".$script.'?target=' . rawurlencode($path) . "';}"; return $this->linkItem( $this->label($type), $this->excludeIcon('PH_backPath,'gfx/'.$image,'width="12" height="12"').' alt="" />'), - $editOnClick.'return hideCM();' + $editOnClick . 'top.nav.refresh();return hideCM();' ); } else { return $this->FILE_launch($path, $script, $type, $image, true); @@ -996,14 +1000,14 @@ */ function FILE_delete($path) { $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; if($GLOBALS['BE_USER']->jsConfirmation(4)) { $conf = "confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.delete'),basename($path)).t3lib_BEfunc::referenceCount('_FILE',$path,' (There are %s reference(s) to this file!)')).")"; } else { $conf = '1==1'; } $editOnClick = 'if(' . $loc . " && " . $conf . " ){" . $loc . ".location.href=top.TS.PATH_typo3+'tce_file.php?redirect='+top.rawurlencode(" . $this->frameLocation($loc . '.document') . ")+'" . - "&file[delete][0][data]=".rawurlencode($path).'&vC='.$GLOBALS['BE_USER']->veriCode()."';hideCM();}"; + "&file[delete][0][data]=".rawurlencode($path).'&vC='.$GLOBALS['BE_USER']->veriCode()."';}hideCM();"; return $this->linkItem( $this->label('delete'), @@ -1023,7 +1027,7 @@ */ function FILE_paste($path,$target,$elInfo) { $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; if($GLOBALS['BE_USER']->jsConfirmation(2)) { $conf=$loc." && confirm(".$GLOBALS['LANG']->JScharCode(sprintf($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.php:mess.'.($elInfo[2]=='copy'?'copy':'move').'_into'),$elInfo[0],$elInfo[1])).")"; } else { @@ -1031,7 +1035,7 @@ } $editOnClick='if('.$conf.'){'.$loc.".location.href=top.TS.PATH_typo3+'".$this->clipObj->pasteUrl('_FILE',$path,0). - "&redirect='+top.rawurlencode(" . $this->frameLocation($loc . '.document') .'); hideCM();}'; + "&redirect='+top.rawurlencode(" . $this->frameLocation($loc . '.document') .'); }hideCM();top.nav.refresh();'; return $this->linkItem( $this->label('pasteinto'), @@ -1118,9 +1122,9 @@ function dragDrop_copymovepage($srcUid,$dstUid,$action,$into) { $negativeSign = ($into == 'into') ? '' : '-'; $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_db.php?redirect="+top.rawurlencode(' . $this->frameLocation($loc . '.document') . ')+"' . - '&cmd[pages]['.$srcUid.']['.$action.']='.$negativeSign.$dstUid.'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode().'";hideCM();}'; + '&cmd[pages]['.$srcUid.']['.$action.']='.$negativeSign.$dstUid.'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode().'";}hideCM();top.nav.refresh();'; return $this->linkItem( $this->label($action.'Page_'.$into), @@ -1142,9 +1146,9 @@ */ function dragDrop_copymovefolder($srcPath,$dstPath,$action) { $editOnClick=''; - $loc='top.content'.($this->listFrame && !$this->alwaysContentFrame ?'.list_frame':''); + $loc = 'top.content.list_frame'; $editOnClick = 'if(' . $loc . '){' . $loc . '.document.location=top.TS.PATH_typo3+"tce_file.php?redirect="+top.rawurlencode(' . $this->frameLocation($loc . '.document') .')+"' . - '&file['.$action.'][0][data]='.$srcPath.'&file['.$action.'][0][target]='.$dstPath.'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode().'";hideCM();}'; + '&file['.$action.'][0][data]='.$srcPath.'&file['.$action.'][0][target]='.$dstPath.'&prErr=1&vC='.$GLOBALS['BE_USER']->veriCode().'";}hideCM();top.nav.refresh();'; return $this->linkItem( $this->label($action.'Folder_into'), Index: typo3/alt_db_navframe.php =================================================================== --- typo3/alt_db_navframe.php (revision 8834) +++ typo3/alt_db_navframe.php (working copy) @@ -179,13 +179,8 @@ theUrl += "?id=" + id } top.fsMod.currentBank = bank; + top.TYPO3.Backend.ContentContainer.setUrl(theUrl); - if (top.TYPO3.configuration.condensedMode) { - top.content.location.href = theUrl; - } else { - parent.list_frame.location.href=theUrl; - } - '.($this->doHighlight ? 'Tree.highlightActiveItem("web", highlightID + "_" + bank);' : '').' '.(!$GLOBALS['CLIENT']['FORMSTYLE'] ? '' : 'if (linkObj) linkObj.blur(); ').' return false; Index: typo3/alt_file_navframe.php =================================================================== --- typo3/alt_file_navframe.php (revision 8834) +++ typo3/alt_file_navframe.php (working copy) @@ -195,13 +195,8 @@ theUrl += "?id=" + id } top.fsMod.currentBank = bank; + top.TYPO3.Backend.ContentContainer.setUrl(theUrl); - if (top.TYPO3.configuration.condensedMode) { - top.content.location.href = theUrl; - } else { - parent.list_frame.location.href=theUrl; - } - '.($this->doHighlight ? 'Tree.highlightActiveItem("file", highlightID + "_" + bank);' : '').' '.(!$CLIENT['FORMSTYLE'] ? '' : 'if (linkObj) linkObj.blur(); ').' return false; Index: typo3/backend.php =================================================================== --- typo3/backend.php (revision 8834) +++ typo3/backend.php (working copy) @@ -122,7 +122,6 @@ 'contrib/swfupload/plugins/swfupload.queue.js', 'md5.js', 'js/common.js', - 'js/extjs/backendsizemanager.js', 'js/toolbarmanager.js', 'js/modulemenu.js', 'js/iecompatibility.js', @@ -134,6 +133,7 @@ 'js/loginrefresh.js', 'js/extjs/debugPanel.js', 'js/extjs/viewport.js', + 'js/extjs/iframepanel.js', 'js/extjs/viewportConfiguration.js', ); @@ -197,34 +197,17 @@ $logo = t3lib_div::makeInstance('TYPO3Logo'); $logo->setLogo('gfx/typo3logo_mini.png'); - $menu = $this->moduleMenu->render(); - if ($this->menuWidth != $this->menuWidthDefault) { - $this->css .= ' - #typo3-top { - margin-left: ' . $this->menuWidth . 'px; - } - '; - } // create backend scaffolding $backendScaffolding = ' -
' . $this->renderToolbar() . '
-
-
' . - $menu . - '
-
- -
-
-
+ '; /****************************************************** @@ -351,8 +334,6 @@ protected function generateJavascript() { $pathTYPO3 = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/'; - $goToModuleSwitch = $this->moduleMenu->getGotoModuleJavascript(); - $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')); @@ -405,6 +386,7 @@ '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'), + 'loadingIndicator' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:loadingIndicator'), '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'), @@ -483,9 +465,7 @@ this.denyFileTypes = TYPO3.configuration.denyFileTypes; } var TS = new typoSetup(); - - var currentModuleLoaded = ""; - + //backwards compatibility /** * Frameset Module object * @@ -500,16 +480,16 @@ this.currentMainLoaded=""; this.currentBank="0"; } - var fsMod = new fsModules();' . $moduleFramesHelper . ';'; + var fsMod = new fsModules(); - // add goToModule code - $this->pageRenderer->addExtOnReadyCode(' - top.goToModule = ' . $goToModuleSwitch . '; - '); + top.goToModule = function(modName, cMR_flag, addGetVars) { + TYPO3.ModuleMenu.App.showModule(modName, addGetVars); + } + ' . $this->setStartupModule(); // Check editing of page: $this->handlePageEditing(); - $this->setStartupModule(); + } /** @@ -586,17 +566,14 @@ $moduleParameters = t3lib_div::_GET('modParams'); if($startModule) { - $this->pageRenderer->addExtOnReadyCode(' - // start in module: - function startInModule(modName, cMR_flag, addGetVars) { - Ext.onReady(function() { - top.goToModule(modName, cMR_flag, addGetVars); - }); + return ' + // start in module: + top.startInModule = [\'' . $startModule . '\', ' . t3lib_div::quoteJSvalue($moduleParameters) . ']; + '; + } else { + return ''; } - startInModule(\''.$startModule.'\', false, '.t3lib_div::quoteJSvalue($moduleParameters).'); - '); - } } /** Index: typo3/classes/class.modulemenu.php =================================================================== --- typo3/classes/class.modulemenu.php (revision 8834) +++ typo3/classes/class.modulemenu.php (working copy) @@ -49,8 +49,8 @@ protected $backPath; protected $linkModules; protected $loadedModules; - protected $fsMod; //TODO find a more descriptive name, left over from alt_menu_functions + /** * constructor, initializes several variables * @@ -59,7 +59,6 @@ public function __construct() { $this->backPath = ''; - $this->fsMod = array(); $this->linkModules = true; // Loads the backend modules available for the logged in user. @@ -100,128 +99,82 @@ } /** - * returns the loaded modules + * ModuleMenu Store loading data * - * @return array array of loaded modules + * @param array_type $params + * @param object $ajaxObj */ - public function getLoadedModules() { - return $this->loadedModules; - } - - /** - * saves the menu's toggle state in the backend user's uc - * - * @param array array of parameters from the AJAX interface, currently unused - * @param TYPO3AJAX object of type TYPO3AJAX - * @return void - */ - public function saveMenuState($params, $ajaxObj) { - $menuItem = t3lib_div::_POST('menuid'); - $state = t3lib_div::_POST('state') === 'true' ? 1 : 0; - - $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$menuItem] = $state; - $GLOBALS['BE_USER']->writeUC(); - } - - /** - * renders the backend menu as unordered list - * - * @param boolean optional parameter used to switch wrapping the menu in ul tags off for AJAX calls - * @return string menu html code to use in the backend - */ - public function render($wrapInUl = true) { - $menu = ''; - $onBlur = $GLOBALS['CLIENT']['FORMSTYLE'] ? 'this.blur();' : ''; - - $tsConfiguration = $GLOBALS['BE_USER']->getTSConfig('options.moduleMenuCollapsable'); - $collapsable = (isset($tsConfiguration['value']) && $tsConfiguration['value'] == 0) ? 0 : 1; - + public function getModuleData($params, $ajaxObj) { + $data = array('success' => TRUE, 'root' => array()); $rawModuleData = $this->getRawModuleData(); - + $index = 0; foreach($rawModuleData as $moduleKey => $moduleData) { + $key = substr($moduleKey, 8); + $num = count($data['root']); if($moduleData['link'] != 'dummy.php' || ($moduleData['link'] == 'dummy.php' && is_array($moduleData['subitems'])) ) { - $menuState = $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$moduleKey]; - $moduleLabel = $moduleData['title']; + $data['root'][$num]['key'] = $key; + $data['root'][$num]['menuState'] = $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$moduleKey]; + $data['root'][$num]['label'] = $moduleData['title']; + $data['root'][$num]['subitems'] = is_array($moduleData['subitems']) ? count($moduleData['subitems']) : 0; + if($moduleData['link'] && $this->linkModules) { - $moduleLabel = '' . $moduleLabel . ''; + $data['root'][$num]['link'] = 'top.goToModule(\'' . $moduleData['name'] . '\')'; } - $menu .= '
  • -
    ' . - $moduleData['icon']['html'] . ' ' . $moduleLabel . '
    '; - // traverse submodules if (is_array($moduleData['subitems'])) { - $menu .= $this->renderSubModules($moduleData['subitems'], $menuState); + foreach($moduleData['subitems'] as $subKey => $subData) { + $data['root'][$num]['sub'][] = array( + 'name' => $subData['name'], + 'description' => $subData['description'], + 'label' => $subData['title'], + 'icon' => $subData['icon']['filename'], + 'navframe' => $subData['parentNavigationFrameScript'], + 'link' => $subData['link'], + 'originalLink' => $subData['originalLink'], + 'index' => $index++, + 'navigationFrameScript' => $subData['navFrameScript'], + 'navigationFrameScriptParam' => $subData['navFrameScriptParam'], + ); + } } - - $menu .= '
  • ' . LF; } } + if ($ajaxObj) { + $ajaxObj->setContent($data); + $ajaxObj->setContentFormat('jsonbody'); - return ($wrapInUl ? '' . LF : $menu); + } else { + return $data; + } } /** - * renders the backend menu as unordered list as an AJAX response without - * the wrapping ul tags + * returns the loaded modules * - * @param array array of parameters from the AJAX interface, currently unused - * @param TYPO3AJAX object of type TYPO3AJAX - * @return void + * @return array array of loaded modules */ - public function renderAjax($params = array(), TYPO3AJAX &$ajaxObj = null) { - $menu = $this->render(false); - $menuSwitch = $this->getGotoModuleJavascript(); - - // JS rocks: we can just overwrite a function with a new definition. - // and yes, we actually do that =) - $menuSwitchUpdate = ' - '; - - $ajaxObj->addContent('typo3-menu', $menu.$menuSwitchUpdate); + public function getLoadedModules() { + return $this->loadedModules; } /** - * renders submodules + * saves the menu's toggle state in the backend user's uc * - * @param array array of (sub)module data - * @param boolean collapse state of menu item, defaults to false - * @return string (sub)module html code + * @param array array of parameters from the AJAX interface, currently unused + * @param TYPO3AJAX object of type TYPO3AJAX + * @return void */ - public function renderSubModules($modules, $menuState=false) { - $moduleMenu = ''; - $onBlur = $GLOBALS['CLIENT']['FORMSTYLE'] ? 'this.blur();' : ''; + public function saveMenuState($params, $ajaxObj) { + $menuItem = t3lib_div::_POST('menuid'); + $state = t3lib_div::_POST('state') === 'true' ? 1 : 0; - foreach($modules as $moduleKey => $moduleData) { - // Setting additional JavaScript - $additionalJavascript = ''; - if($moduleData['parentNavigationFrameScript']) { - $parentModuleName = substr($moduleData['name'], 0, strpos($moduleData['name'], '_')); - $additionalJavascript = "+'&id='+top.rawurlencodeAndRemoveSiteUrl(top.fsMod.recentIds['" . $parentModuleName . "'])"; - } - - if($moduleData['link'] && $this->linkModules) { - - $onClickString = htmlspecialchars('top.goToModule(\''.$moduleData['name'].'\');'.$onBlur.'return false;'); - $submoduleLink = '' - //TODO make icon a background image using css - .''.$moduleData['icon']['html'].'' - .''.htmlspecialchars($moduleData['title']).'' - .''; - } - - $moduleMenu .= '
  • ' . $submoduleLink . '
  • ' . LF; - } - - return ''.LF.$moduleMenu.''.LF; + $GLOBALS['BE_USER']->uc['moduleData']['menuState'][$menuItem] = $state; + $GLOBALS['BE_USER']->writeUC(); } + /** * gets the raw module data * @@ -236,12 +189,6 @@ } foreach($this->loadedModules as $moduleName => $moduleData) { - $moduleNavigationFramePrefix = $this->getNavigationFramePrefix($moduleData); - - if($moduleNavigationFramePrefix) { - $this->fsMod[$moduleName] = 'fsMod.recentIds["'.$moduleName.'"]="";'; - } - $moduleLink = ''; if(!is_array($moduleData['sub'])) { $moduleLink = $moduleData['script']; @@ -251,17 +198,12 @@ $moduleKey = 'modmenu_' . $moduleName; $moduleIcon = $this->getModuleIcon($moduleKey); - if($moduleLink && $moduleNavigationFramePrefix) { - $moduleLink = $moduleNavigationFramePrefix.rawurlencode($moduleLink); - } - $modules[$moduleKey] = array( 'name' => $moduleName, 'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$moduleName . '_tab'], 'onclick' => 'top.goToModule(\''.$moduleName.'\');', 'icon' => $moduleIcon, 'link' => $moduleLink, - 'prefix' => $moduleNavigationFramePrefix, 'description' => $GLOBALS['LANG']->moduleLabels['labels'][$moduleKey.'label'] ); @@ -269,25 +211,20 @@ foreach($moduleData['sub'] as $submoduleName => $submoduleData) { $submoduleLink = t3lib_div::resolveBackPath($submoduleData['script']); - $submoduleNavigationFramePrefix = $this->getNavigationFramePrefix($moduleData, $submoduleData); - $submoduleKey = $moduleName.'_'.$submoduleName.'_tab'; + $submoduleKey = $moduleName . '_' . $submoduleName . '_tab'; $submoduleIcon = $this->getModuleIcon($submoduleKey); - $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey.'label']; + $submoduleDescription = $GLOBALS['LANG']->moduleLabels['labels'][$submoduleKey . 'label']; $originalLink = $submoduleLink; - if($submoduleLink && $submoduleNavigationFramePrefix) { - $submoduleLink = $submoduleNavigationFramePrefix.rawurlencode($submoduleLink); - } $modules[$moduleKey]['subitems'][$submoduleKey] = array( - 'name' => $moduleName.'_'.$submoduleName, + 'name' => $moduleName . '_' . $submoduleName, 'title' => $GLOBALS['LANG']->moduleLabels['tabs'][$submoduleKey], - 'onclick' => 'top.goToModule(\''.$moduleName.'_'.$submoduleName.'\');', + 'onclick' => 'top.goToModule(\'' . $moduleName . '_' . $submoduleName . '\');', 'icon' => $submoduleIcon, 'link' => $submoduleLink, 'originalLink' => $originalLink, - 'prefix' => $submoduleNavigationFramePrefix, 'description' => $submoduleDescription, 'navigationFrameScript' => $submoduleData['navFrameScript'], 'navigationFrameScriptParam' => $submoduleData['navFrameScriptParam'] @@ -326,7 +263,8 @@ $icon['filename'] = $iconFileRelative; $icon['size'] = $iconSizes[3]; $icon['title'] = htmlspecialchars($iconTitle); - $icon['html'] = ''.htmlspecialchars($iconTitle).''; + $icon['html'] = '' . htmlspecialchars($iconTitle) . ''; } return $icon; @@ -364,176 +302,9 @@ return $this->backPath.$iconFilename; } - /** - * Returns a prefix used to call the navigation frame with parameters which then will call the scripts defined in the modules info array. - * - * @param array module data array - * @param array submodule data array - * @return string result URL string - */ - protected function getNavigationFramePrefix($moduleData, $subModuleData = array()) { - $prefix = ''; - $navigationFrameScript = $moduleData['navFrameScript']; - if($subModuleData['navFrameScript']) { - $navigationFrameScript = $subModuleData['navFrameScript']; - } - $navigationFrameParameter = $moduleData['navFrameScriptParam']; - if($subModuleData['navFrameScriptParam']) { - $navigationFrameParameter = $subModuleData['navFrameScriptParam']; - } - - if($navigationFrameScript) { - $navigationFrameScript = t3lib_div::resolveBackPath($navigationFrameScript); - $navigationFrameScript = $this->appendQuestionmarkToLink($navigationFrameScript); - - if($GLOBALS['BE_USER']->uc['condensedMode']) { - $prefix = $navigationFrameScript.$navigationFrameParameter.'¤tSubScript='; - } else { - $prefix = 'alt_mod_frameset.php?' - .'fW="+top.TS.navFrameWidth+"' - .'&nav="+top.TS.PATH_typo3+"' - .rawurlencode($navigationFrameScript.$navigationFrameParameter) - .'&script='; - } - } - - return $prefix; - } - /** - * generates javascript code to switch between modules - * - * @return string javascript code snippet to switch modules - */ - public function getGotoModuleJavascript() { - - $moduleJavascriptCommands = array(); - $rawModuleData = $this->getRawModuleData(); - $navFrameScripts = array(); - - foreach($rawModuleData as $mainModuleKey => $mainModuleData) { - if ($mainModuleData['subitems']) { - foreach ($mainModuleData['subitems'] as $subModuleKey => $subModuleData) { - - $parentModuleName = substr($subModuleData['name'], 0, strpos($subModuleData['name'], '_')); - $javascriptCommand = ''; - - // Setting additional JavaScript if frameset script: - $additionalJavascript = ''; - if($subModuleData['parentNavigationFrameScript']) { - $additionalJavascript = "+'&id='+top.rawurlencodeAndRemoveSiteUrl(top.fsMod.recentIds['" . $parentModuleName . "'])"; - } - - if ($subModuleData['link'] && $this->linkModules) { - // For condensed mode, send &cMR parameter to frameset script. - if ($additionalJavascript && $GLOBALS['BE_USER']->uc['condensedMode']) { - $additionalJavascript .= "+(cMR ? '&cMR=1' : '')"; - } - - $javascriptCommand = ' - modScriptURL = "'.$this->appendQuestionmarkToLink($subModuleData['link']).'"'.$additionalJavascript.';'; - - if ($subModuleData['navFrameScript']) { - $javascriptCommand .= ' - top.currentSubScript="'.$subModuleData['originalLink'].'";'; - } - - if (!$GLOBALS['BE_USER']->uc['condensedMode'] && $subModuleData['parentNavigationFrameScript']) { - $additionalJavascript = "+'&id='+top.rawurlencodeAndRemoveSiteUrl(top.fsMod.recentIds['" . $parentModuleName . "'])"; - - $submoduleNavigationFrameScript = $subModuleData['navigationFrameScript'] ? $subModuleData['navigationFrameScript'] : $subModuleData['parentNavigationFrameScript']; - $submoduleNavigationFrameScript = t3lib_div::resolveBackPath($submoduleNavigationFrameScript); - - // Add navigation script parameters if module requires them - if ($subModuleData['navigationFrameScriptParam']) { - $submoduleNavigationFrameScript = $this->appendQuestionmarkToLink($submoduleNavigationFrameScript) . $subModuleData['navigationFrameScriptParam']; - } - - $navFrameScripts[$parentModuleName] = $submoduleNavigationFrameScript; - - $javascriptCommand = ' - top.currentSubScript = "'.$subModuleData['originalLink'].'"; - if (top.content.list_frame && top.fsMod.currentMainLoaded == mainModName) { - modScriptURL = "'.$this->appendQuestionmarkToLink($subModuleData['originalLink']).'"'.$additionalJavascript.'; - '; - // Change link to navigation frame if submodule has it's own navigation - if ($submoduleNavigationFrameScript) { - $javascriptCommand .= 'navFrames["' . $parentModuleName . '"] = "'. $submoduleNavigationFrameScript . '";'; - } - $javascriptCommand .= ' - } else if (top.nextLoadModuleUrl) { - modScriptURL = "'.($subModuleData['prefix'] ? $this->appendQuestionmarkToLink($subModuleData['link']) . '&exScript=' : '') . 'listframe_loader.php"; - } else { - modScriptURL = "'.$this->appendQuestionmarkToLink($subModuleData['link']).'"'.$additionalJavascript.' + additionalGetVariables; - }'; - } - } - $moduleJavascriptCommands[] = " - case '".$subModuleData['name']."':".$javascriptCommand." - break;"; - } - } elseif(!$mainModuleData['subitems'] && !empty($mainModuleData['link'])) { - // main module has no sub modules but instead is linked itself (doc module f.e.) - $javascriptCommand = ' - modScriptURL = "'.$this->appendQuestionmarkToLink($mainModuleData['link']).'";'; - $moduleJavascriptCommands[] = " - case '".$mainModuleData['name']."':".$javascriptCommand." - break;"; - } - } - - $javascriptCode = 'function(modName, cMR_flag, addGetVars) { - var useCondensedMode = '.($GLOBALS['BE_USER']->uc['condensedMode'] ? 'true' : 'false').'; - var mainModName = (modName.slice(0, modName.indexOf("_")) || modName); - - var additionalGetVariables = ""; - if (addGetVars) { - additionalGetVariables = addGetVars; - }'; - - $javascriptCode .= ' - var navFrames = {};'; - foreach ($navFrameScripts as $mainMod => $frameScript) { - $javascriptCode .= ' - navFrames["'.$mainMod.'"] = "'.$frameScript.'";'; - } - - $javascriptCode .= ' - - var cMR = (cMR_flag ? 1 : 0); - var modScriptURL = ""; - - switch(modName) {' - .LF.implode(LF, $moduleJavascriptCommands).LF.' - } - '; - - $javascriptCode .= ' - - if (!useCondensedMode && navFrames[mainModName]) { - if (top.content.list_frame && top.fsMod.currentMainLoaded == mainModName) { - top.content.list_frame.location = top.getModuleUrl(top.TS.PATH_typo3 + modScriptURL + additionalGetVariables); - if (top.currentSubNavScript != navFrames[mainModName]) { - top.currentSubNavScript = navFrames[mainModName]; - top.content.nav_frame.location = top.getModuleUrl(top.TS.PATH_typo3 + navFrames[mainModName]); - } - } else { - TYPO3.Backend.loadModule(mainModName, modName, modScriptURL + additionalGetVariables); - } - } else if (modScriptURL) { - TYPO3.Backend.loadModule(mainModName, modName, top.getModuleUrl(modScriptURL + additionalGetVariables)); - } - currentModuleLoaded = modName; - top.fsMod.currentMainLoaded = mainModName; - TYPO3ModuleMenu.highlightModule("modmenu_" + modName, (modName == mainModName ? 1 : 0)); - }'; - - return $javascriptCode; - } - - /** * Appends a '?' if there is none in the string already * * @param string Link URL @@ -576,14 +347,6 @@ $this->linkModules = $linkModules; } - /** - * gets the frameset (leftover) helper - * - * @return array array of javascript snippets - */ - public function getFsMod() { - return $this->fsMod; - } } Index: typo3/js/backend.js =================================================================== --- typo3/js/backend.js (revision 8834) +++ typo3/js/backend.js (working copy) @@ -28,7 +28,6 @@ * general backend javascript functions */ - Ext.ns('TYPO3.configuration'); /** @@ -38,12 +37,13 @@ // clear information about which entry in nav. tree that might have been highlighted. top.fsMod.navFrameHighlightedID = []; - if (top.content && top.content.nav_frame && top.content.nav_frame.refresh_nav) { - top.content.nav_frame.refresh_nav(); + if (top.TYPO3.Backend.NavigationContainer.isVisible()) { + top.TYPO3.Backend.NavigationContainer.refresh(); } top.nextLoadModuleUrl = url; - top.goToModule(modName); + top.TYPO3.ModuleMenu.App.showModule(modName); + } /** Index: typo3/js/extjs/debugPanel.js =================================================================== --- typo3/js/extjs/debugPanel.js (revision 8834) +++ typo3/js/extjs/debugPanel.js (working copy) @@ -47,7 +47,7 @@ TYPO3.DebugPanel = Ext.extend(Ext.TabPanel, { /** * Tab Groups - * + * * @var Ext.util.MixedCollection */ tabGroups: new Ext.util.MixedCollection(), @@ -55,7 +55,7 @@ /** * Indicator if the debug panel is wrapped inside a debug panel * @see addTabWidget() - * + * * @var boolean */ isTabChildren: false, @@ -111,7 +111,7 @@ }) }); - + TYPO3.DebugPanel.superclass.initComponent.call(this); }, @@ -129,13 +129,9 @@ ); this.arrow.hide(); - this.on('move', function() { - this.ownerCt.fireEvent('resize'); - }, this); - TYPO3.DebugPanel.superclass.onRender.apply(this, arguments); }, - + /** * Collapse event * @@ -143,7 +139,6 @@ */ onCollapse: function() { TYPO3.DebugPanel.superclass.onCollapse.apply(this, arguments); - this.ownerCt.fireEvent('resize'); }, /** @@ -153,7 +148,6 @@ */ onExpand: function() { TYPO3.DebugPanel.superclass.onExpand.apply(this, arguments); - this.ownerCt.fireEvent('resize'); }, /** @@ -191,7 +185,7 @@ closable: true, draggableTab: true }); - + this.addTabWidget(tabWidget, group, position); } }, @@ -211,7 +205,6 @@ addTabWidget: function(tabWidget, group, position) { if (this.hidden) { this.show(); - this.ownerCt.fireEvent('resize'); } else if (this.collapsed) { this.expand(); } @@ -251,7 +244,7 @@ } else { if (!this.items.getCount()) { this.hide(); - this.ownerCt.fireEvent('resize'); + this.ownerCt.doLayout(); } this.tabGroups.removeKey(element.title); } @@ -459,10 +452,10 @@ } }); }, - + /** * Opens debug output in a new browser window - * + * * @param title string * @param content string * @param group string @@ -487,7 +480,7 @@ } newWindow.document.close() }, - + /** * Wrapper for console.log * @@ -500,7 +493,7 @@ } } }, - + /** * Wrapper for console.info * @@ -513,7 +506,7 @@ } } }, - + /** * Wrapper for console.warn * @@ -526,7 +519,7 @@ } } }, - + /** * Wrapper for console.error * @@ -539,10 +532,10 @@ } } }, - + /** * Debug output from javascript - * + * * @param out mixed debug output * @param header string * @param group string @@ -551,10 +544,10 @@ var output = this.printObject(out); this.addTab(output, header, group); }, - + /** * Converts any string/array/object to a string for printing purposes - * + * * @param object object * @param level integer recursion level counter (max. 3 levels) * @param prefix string internal use! @@ -594,7 +587,7 @@ return '
    ' + result + '
    '; }, - + /** * Debug attached events of a given element (e.g. an Ext.Panel component) * Index: typo3/js/extjs/iframepanel.js =================================================================== --- typo3/js/extjs/iframepanel.js (revision 0) +++ typo3/js/extjs/iframepanel.js (revision 0) @@ -0,0 +1,110 @@ +/*************************************************************** +* Copyright notice +* +* (c) 2010 Steffen Kamper +* All rights reserved +* +* This script is part of the TYPO3 project. The TYPO3 project is +* free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* The GNU General Public License can be found at +* http://www.gnu.org/copyleft/gpl.html. +* A copy is found in the textfile GPL.txt and important notices to the license +* from the author is found in LICENSE.txt distributed with these scripts. +* +* +* This script is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* This copyright notice MUST APPEAR in all copies of the script! +***************************************************************/ + + +/** + * iFrame panel + * + * @author Steffen Kamper + */ + +Ext.ns('TYPO3'); + +TYPO3.iframePanel = Ext.extend(Ext.Panel, { + name: 'iframe', + iframe: null, + src: Ext.isIE && Ext.isSecure ? Ext.SSL_SECURE_URL : 'about:blank', + maskMessage: 'loading ...', + doMask: true, + + // component build + initComponent: function() { + this.bodyCfg = { + tag: 'iframe', + frameborder: '0', + src: this.src, + name: this.name + } + Ext.apply(this, { + + }); + TYPO3.iframePanel.superclass.initComponent.apply(this, arguments); + + // apply the addListener patch for 'message:tagging' + this.addListener = this.on; + + }, + + onRender : function() { + TYPO3.iframePanel.superclass.onRender.apply(this, arguments); + this.maskMessage = TYPO3.LLL.core.loadingIndicator; + this.iframe = Ext.isIE ? this.body.dom.contentWindow : window.frames[this.name]; + this.body.dom[Ext.isIE ? 'onreadystatechange' : 'onload'] = this.loadHandler.createDelegate(this); + }, + + loadHandler: function() { + this.src = this.body.dom.src; + this.removeMask(); + }, + + getIframe: function() { + return this.iframe; + }, + getUrl: function() { + return this.body.dom.src; + }, + + setUrl: function(source) { + this.setMask(); + this.body.dom.src = source; + }, + + resetUrl: function() { + this.setMask(); + this.body.dom.src = this.src; + }, + + refresh: function() { + if (!this.isVisible()) { + return; + } + this.setMask(); + this.body.dom.src = this.body.dom.src; + }, + + /** @private */ + setMask: function() { + if (this.doMask) { + this.el.mask(this.maskMessage, 'x-mask-loading'); + } + }, + removeMask: function() { + if (this.doMask) { + this.el.unmask(); + } + } +}); +Ext.reg('iframePanel', TYPO3.iframePanel); Index: typo3/js/extjs/viewport.js =================================================================== --- typo3/js/extjs/viewport.js (revision 8834) +++ typo3/js/extjs/viewport.js (working copy) @@ -89,18 +89,25 @@ * @return void */ initComponent: function() { - // adjust the width of module menu and the height of the topbar + // adjust the module menu and the height of the topbar this.initialConfig.items[0].height = TYPO3.configuration.topBarHeight; - this.initialConfig.items[1].width = TYPO3.configuration.moduleMenuWidth; + + var moduleMenu = this.initialConfig.items[1]; + moduleMenu.width = TYPO3.configuration.moduleMenuWidth; + if (!TYPO3.configuration.moduleMenuSplit) { + moduleMenu.split = false; + moduleMenu.collapsible = false; + moduleMenu.collapseMode = null + } // call parent constructor TYPO3.Viewport.superclass.initComponent.apply(this, arguments); - this.ContentContainer = Ext.ComponentMgr.get('typo3-contentContainer'); - this.NavigationContainer = Ext.ComponentMgr.get('typo3-navigationContainer'); - this.Topbar = Ext.ComponentMgr.get('typo3-topbar'); - this.ModuleMenuContainer = Ext.ComponentMgr.get('typo3-module-menu'); - this.DebugConsole = Ext.ComponentMgr.get('typo3-debug-console'); + this.ContentContainer = Ext.getCmp('typo3-contentContainer'); + this.NavigationContainer = Ext.getCmp('typo3-navigationContainer'); + this.Topbar = Ext.getCmp('typo3-topbar'); + this.ModuleMenuContainer = Ext.getCmp('typo3-module-menu'); + this.DebugConsole = Ext.getCmp('typo3-debug-console'); }, /** @@ -142,10 +149,8 @@ if (contentScript.indexOf(top.TS.PATH_typo3) !== 0) { contentScript = top.TS.PATH_typo3 + contentScript; } - Ext.get('content').set({ - src: contentScript - }); - + this.ContentContainer.setUrl(contentScript); + this.NavigationContainer.ownerCt.doLayout(); }, Index: typo3/js/extjs/viewportConfiguration.js =================================================================== --- typo3/js/extjs/viewportConfiguration.js (revision 8834) +++ typo3/js/extjs/viewportConfiguration.js (working copy) @@ -44,38 +44,45 @@ contentEl: 'typo3-top-container', border: false }, { - layout: 'absolute', + layout: 'fit', region: 'west', id: 'typo3-module-menu', - contentEl: 'typo3-side-menu', - width: 159, - anchor: '100% 100%', - border: false + collapsible: true, + collapseMode: 'mini', + floatable: true, + hideCollapseTool: true, + split: true, + border: false, + autoScroll: true }, { region: 'center', layout: 'border', border: false, items: [{ region: 'west', - layout: 'absolute', + layout: 'fit', id: 'typo3-navigationContainer', width: 300, - anchor: '100% 100%', + minWidth: 20, + floatable: true, + animCollapse: false, + split: true, collapsible: true, collapseMode: 'mini', hideCollapseTool: true, - animCollapse: false, - split: true, autoScroll: true, hidden: true, - border: false + border: false, + xtype: 'iframePanel', + name: 'navigation' }, { region: 'center', - layout: 'absolute', + layout: 'fit', id: 'typo3-contentContainer', - contentEl: 'typo3-content', anchor: '100% 100%', - border: false + border: false, + xtype: 'iframePanel', + name: 'content' }] }, { region: 'south', Index: typo3/js/modulemenu.js =================================================================== --- typo3/js/modulemenu.js (revision 8834) +++ typo3/js/modulemenu.js (working copy) @@ -1,7 +1,7 @@ /*************************************************************** * Copyright notice * -* (c) 2007-2010 Ingo Renner +* (c) 2010 Steffen Kamper * All rights reserved * * This script is part of the TYPO3 project. The TYPO3 project is @@ -26,143 +26,279 @@ /** - * observes clicks on menuHeader and toggles child ul + * Class to render the module menu and handle the BE navigation * - * @author Ingo Renner * @author Steffen Kamper */ -var ModuleMenu = Class.create({ - /** - * initially register event listeners - */ - initialize: function() { - // initialize event listeners - Event.observe(document, 'dom:loaded', function(){ - this.registerEventListeners(); - }.bind(this)); +Ext.ns('TYPO3', 'ModuleMenu'); - // initialize some variables - this.currentlyHighLightedMainModule = ''; - this.currentlyHighlightedModuleId = ''; +TYPO3.ModuleMenu = {}; + +TYPO3.ModuleMenu.Store = new Ext.data.JsonStore({ + storeId: 'ModuleMenuStore', + root: 'root', + fields: [ + {name: 'index', type: 'int', mapping: 'sub.index'}, + {name: 'key', type: 'string'}, + {name: 'label', type: 'string'}, + {name: 'menuState', type: 'int'}, + {name: 'subitems', type: 'int'}, + 'sub' + ], + url: 'ajax.php?ajaxID=ModuleMenu::getData', + baseParams: { + 'action': 'getModules' + } + +}); + +TYPO3.ModuleMenu.Template = new Ext.XTemplate( + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '
    ', + '', + { + getStateClass: function(value) { + return value.menuState ? 'collapsed' : 'expanded'; + }, + getStateStyle: function(value) { + return value.menuState ? 'style="display:none"' : ''; + } + } +); + +TYPO3.ModuleMenu.App = { + loadedModule: null, + + init: function() { + TYPO3.ModuleMenu.Store.load({ + scope: this, + callback: function(records, options) { + this.renderMenu(records); + if (top.startInModule) { + this.showModule(top.startInModule[0],top.startInModule[1]); + } + } + }); }, - /** - * registers the event listeners, can be used to re-register them after refreshing the menu - */ - registerEventListeners: function() { - $$('#typo3-menu li.menuSection div').invoke('observe', 'click', this.toggleMenu); - if (Prototype.Browser.IE) { - //mouseenter and mouseleave are only available but thats our target - $$('#typo3-menu li.menuSection li').invoke('observe', 'mouseenter', this.toggleHoverClass); - $$('#typo3-menu li.menuSection li').invoke('observe', 'mouseleave', this.toggleHoverClass); + renderMenu: function(records) { + TYPO3.Backend.ModuleMenuContainer.removeAll(); + TYPO3.Backend.ModuleMenuContainer.add({ + xtype: 'dataview', + animCollapse: true, + store: TYPO3.ModuleMenu.Store, + tpl: TYPO3.ModuleMenu.Template, + singleSelect: true, + itemSelector: 'li.submodule', + overClass: 'x-view-over', + selectedClass: 'highlighted', + autoHeight: true, + itemId: 'modDataView', + tbar: [{text: 'test'}], + listeners: { + click: function(view, index, node, event) { + var el = Ext.fly(node); + if (el.hasClass('submodule')) { + TYPO3.ModuleMenu.App.showModule(el.getAttribute('id')); + } + }, + containerclick: function(view, event) { + var item = event.getTarget('li.menuSection', view.getEl()); + if (item) { + var el = Ext.fly(item); + var id = el.getAttribute('id'); + var section = el.first('div'), state; + if (section.hasClass('expanded')) { + state = true; + section.removeClass('expanded').addClass('collapsed'); + el.first('ul').slideOut('t', { + easing: 'easeOut', + duration: .2, + remove: false, + useDisplay: true + }); + + } else { + state = false; + section.removeClass('collapsed').addClass('expanded'); + el.first('ul').slideIn('t', { + easing: 'easeIn', + duration: .2, + remove: false, + useDisplay: true + }); + } + // save menu state + Ext.Ajax.request({ + url: 'ajax.php?ajaxID=ModuleMenu::saveMenuState', + params: { + 'menuid': 'modmenu_' + id, + 'state': state + } + }); + } + }, + scope: this + } + }); + TYPO3.Backend.ModuleMenuContainer.doLayout(); + }, + + getRecordFromIndex: function(index) { + var i, record; + for (i = 0; i < TYPO3.ModuleMenu.Store.getCount(); i++) { + record = TYPO3.ModuleMenu.Store.getAt(i); + if (index < record.data.subitems) { + return record.data.sub[index]; + } + index -= record.data.subitems; } }, - - /** - * toggles the hover classname for IE menu hover support - */ - toggleHoverClass: function(event) { - var menuItem = Event.element(event); - menuItem.toggleClassName('hover'); + + getRecordFromName: function(name) { + var i, j, record; + for (i = 0; i < TYPO3.ModuleMenu.Store.getCount(); i++) { + record = TYPO3.ModuleMenu.Store.getAt(i); + for (j = 0; j < record.data.subitems; j++) { + if (record.data.sub[j].name === name) { + return record.data.sub[j]; + } + } + } }, - /** - * toggles the associated submodule menu when clicking a main module header - */ - toggleMenu: function(event) { - var mainModuleHeader = Event.element(event); + showModule: function(mod, params) { + params = params || ''; + this.selecteModule = mod; + var record = this.getRecordFromName(mod); - var mainMenuId = mainModuleHeader.up().identify(); - var subModulesMenu = mainModuleHeader.next('ul'); - if (!subModulesMenu) { - return; + if (record) { + + //get id + var section = mod.split('_')[0]; + if (top.fsMod.recentIds[section]) { + params = 'id=' + top.fsMod.recentIds[section] + params; + } + + if (record.navframe) { + this.openInNavFrame(record.navframe); + } else { + TYPO3.Backend.NavigationContainer.hide(); + } + this.openInContentFrame(record.originalLink, params); + this.loadedModule = mod; + this.highlightModuleMenuItem(mod); + + // compatibility + top.currentSubScript = record.originalLink; + top.currentModuleLoaded = mod; + + TYPO3.Backend.doLayout(); + } else { + console.log(mod + ' was not found in modules'); } - var state = subModulesMenu.visible(); + }, - // save state - var save = new Ajax.Request('ajax.php', { - parameters : 'ajaxID=ModuleMenu::saveMenuState&menuid=' + mainMenuId + '&state=' + state - }); + openInNavFrame: function(url, params) { + var navUrl = url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : ''); + var currentUrl = this.relativeUrl(TYPO3.Backend.NavigationContainer.getUrl()); + TYPO3.Backend.NavigationContainer.show(); + if (currentUrl !== navUrl) { + TYPO3.Backend.NavigationContainer.setUrl(navUrl); + } + }, - if (state) { - Effect.BlindUp(subModulesMenu, {duration : 0.1}); - $(mainModuleHeader).removeClassName('expanded'); - $(mainModuleHeader).addClassName('collapsed'); + openInContentFrame: function(url, params) { + if (top.nextLoadModuleUrl) { + TYPO3.Backend.ContentContainer.setUrl(top.nextLoadModuleUrl); + top.nextLoadModuleUrl = ''; } else { - Effect.BlindDown(subModulesMenu, {duration : 0.1}); - $(mainModuleHeader).removeClassName('collapsed'); - $(mainModuleHeader).addClassName('expanded'); + TYPO3.Backend.ContentContainer.setUrl(url + (params ? (url.indexOf('?') !== -1 ? '&' : '?') + params : '')); } }, - /** - * refreshes the complete module menu - */ + highlightModuleMenuItem: function(module, mainModule) { + TYPO3.Backend.ModuleMenuContainer.getComponent('modDataView').select(module, false, false); + }, + + relativeUrl: function(url) { + return url.replace(TYPO3.configuration.siteUrl + 'typo3/', ''); + }, + refreshMenu: function() { - var refresh = new Ajax.Updater('typo3-menu', TS.PATH_typo3 + 'ajax.php', { - parameters : 'ajaxID=ModuleMenu::render', - asynchronous : false, - evalScripts : true + TYPO3.ModuleMenu.Store.load({ + scope: this, + callback: function(records, options) { + this.renderMenu(records); + if (this.loadedModule) { + this.highlightModuleMenuItem(this.loadedModule); + } + } }); - - this.registerEventListeners(); - this.highlightModule(this.currentlyHighlightedModuleId, this.currentlyHighLightedMainModule); }, - /** - * de-highlights the old menu item and highlights the new one - * - * @param string css module id to highlight - */ - highlightModule: function(moduleId, mainModule) { - // reset the currently highlighted module - $$('#typo3-menu .highlighted').invoke('removeClassName', 'highlighted'); + reloadFrames: function() { + TYPO3.Backend.NavigationContainer.refresh(); + TYPO3.Backend.ContentContainer.refresh(); + } - // highlight the new one - if ($(moduleId)) { - $(moduleId).addClassName('highlighted'); - } +}; - if (undefined !== mainModule) { - this.currentlyHighLightedMainModule = mainModule; - } - this.currentlyHighlightedModuleId = moduleId; - // kept for backwards compatibility - // @TODO: remove in TYPO3 4.5 - // @deprecated since TYPO3 4.3, remove in 4.5 - top.currentlyHighLightedId = moduleId; - top.currentlyHighLightedMain = mainModule; + +Ext.onReady(function() { + TYPO3.ModuleMenu.App.init(); + + // keep backward compatibility + top.list = TYPO3.Backend.ContentContainer; + top.nav = TYPO3.Backend.NavigationContainer; + top.list_frame = top.list.getIframe(); + top.nav_frame = top.nav.getIframe(); + + top.TYPO3ModuleMenu = TYPO3.ModuleMenu.App; + top.content = { + nav_frame: TYPO3.Backend.NavigationContainer.getIframe(), + list_frame: TYPO3.Backend.ContentContainer.getIframe() } - }); -var TYPO3ModuleMenu = new ModuleMenu(); - /******************************************************************************* - * - * Backwards compatability handling down here - * - ******************************************************************************/ +* +* Backwards compatability handling down here +* +******************************************************************************/ /** - * Highlight module: - */ +* Highlight module: +*/ var currentlyHighLightedId = ''; var currentlyHighLighted_restoreValue = ''; var currentlyHighLightedMain = ''; function highlightModuleMenuItem(trId, mainModule) { - TYPO3ModuleMenu.highlightModule(trId, mainModule); + TYPO3.ModuleMenu.App.highlightModule(trId, mainModule); } - - - - - - - - - Index: typo3/js/workspacemenu.js =================================================================== --- typo3/js/workspacemenu.js (revision 8834) +++ typo3/js/workspacemenu.js (working copy) @@ -171,11 +171,10 @@ // when in web module reload, otherwise send the user to the web module if (currentModuleLoaded.startsWith('web_')) { - // the boolean "true" makes the page reload from the server - $('content').contentWindow.location.reload(true); + top.TYPO3.ModuleMenu.App.reloadFrames(); } else { if (TYPO3.configuration.pageModule) { - top.goToModule(TYPO3.configuration.pageModule); + top.TYPO3.ModuleMenu.App.showModule(TYPO3.configuration.pageModule); } } Index: typo3/sysext/lang/locallang_core.xml =================================================================== --- typo3/sysext/lang/locallang_core.xml (revision 8834) +++ typo3/sysext/lang/locallang_core.xml (working copy) @@ -291,6 +291,7 @@ + Index: typo3/sysext/t3skin/extjs/xtheme-t3skin.css =================================================================== --- typo3/sysext/t3skin/extjs/xtheme-t3skin.css (revision 8834) +++ typo3/sysext/t3skin/extjs/xtheme-t3skin.css (working copy) @@ -1,19 +1,19 @@ -/** +/** * TYPO3 Backend colors defaults! - * + * * Colors: * General Background #EFEFF4 * Dark Grey #D7DBE2 * Text #55545E * headline Text #FFFFFF * Border #A2AAB8 - * + * * Attributes: * font-family verdana, arial, tahoma, helvetica, sans-serif * font-size 10px */ -/* preliminary code for the tabmenu */ +/* preliminary code for the tabmenu */ .x-tab-panel-body .x-panel-body { padding: 10px; background-color: #EFEFF4; @@ -123,14 +123,15 @@ background-image:url(images/panel/light-hd.gif); } -.x-layout-collapsed{ +.x-layout-collapsed { background-color:#EFEFF4; - border-color:#A2AAB8; } + .x-layout-collapsed-over{ - background-color:#EFEFF4; + background-color:#EFEFF4; } + /* qtips */ .x-tip .x-tip-top { background-image:url(images/qtip/tip-sprite.gif); @@ -478,7 +479,7 @@ */ .ext-el-mask { - background-color: #000; + background-color: #aaa; -moz-opacity: 0.75; opacity: .75; filter: alpha(opacity=75); @@ -1229,7 +1230,7 @@ border-bottom-color:#A2AAB8; } -.x-grid-group-hd div.x-grid-group-title { +.x-grid-group-hd div.x-grid-group-title { background-image:url(images/grid/group-expand-sprite.gif); background-position: 3px -46px; color:#3764a0; @@ -2023,9 +2024,8 @@ background-image: url(images/panel/light-hd.gif); } -.x-layout-collapsed{ +.x-layout-collapsed { background-color:#dfdfdf; - border-color:#bcbcbc; } .x-layout-collapsed-over{ @@ -2177,7 +2177,7 @@ /* Pagetree */ .x-layout-split { - background-color: #aeb6c1; + background-color: #dadada; } #widget-navigation-tree .x-panel-noborder .x-panel-body-noborder { Index: typo3/sysext/t3skin/stylesheets/structure/module_menu.css =================================================================== --- typo3/sysext/t3skin/stylesheets/structure/module_menu.css (revision 8834) +++ typo3/sysext/t3skin/stylesheets/structure/module_menu.css (working copy) @@ -8,6 +8,10 @@ padding-top: 22px; } +#typo3-module-menu .x-panel-body { + overflow-x: hidden !important; +} + #typo3-menu ul { padding: 0; margin: 0; @@ -27,7 +31,6 @@ } #typo3-menu li div { - margin: 4px 0px 2px 4px; overflow: hidden; padding: 2px 0px 4px 16px; vertical-align: middle; Index: typo3/sysext/t3skin/stylesheets/visual/module_menu.css =================================================================== --- typo3/sysext/t3skin/stylesheets/visual/module_menu.css (revision 8834) +++ typo3/sysext/t3skin/stylesheets/visual/module_menu.css (working copy) @@ -53,7 +53,7 @@ font-weight: bold; } -#typo3-menu li div { +#typo3-menu li div.modgroup { color: #252524; cursor: pointer; font-weight: bold; Index: typo3/sysext/t3skin/stylesheets/visual/viewport.css =================================================================== --- typo3/sysext/t3skin/stylesheets/visual/viewport.css (revision 0) +++ typo3/sysext/t3skin/stylesheets/visual/viewport.css (revision 0) @@ -0,0 +1,11 @@ +/* - - - - - - - - - - - - - - - - - - - - - +TYPO3 viewport + +$Id$ +- - - - - - - - - - - - - - - - - - - - - */ + + +#typo3-navigationContainer-xsplit, +#typo3-navigationContainer-xcollapsed { + border-top: 22px solid #585858; +} \ No newline at end of file