diff --git a/typo3/sysext/backend/Classes/Controller/BackendController.php b/typo3/sysext/backend/Classes/Controller/BackendController.php index 5adbfed7634192d33fd9646b5e0f6257f7d23d0c..fb5c0fcf87d83c2685ef5c4a0f4ba8829ceafa22 100644 --- a/typo3/sysext/backend/Classes/Controller/BackendController.php +++ b/typo3/sysext/backend/Classes/Controller/BackendController.php @@ -75,6 +75,11 @@ class BackendController */ protected $templatePath = 'EXT:backend/Resources/Private/Templates/'; + /** + * @var string + */ + protected $partialPath = 'EXT:backend/Resources/Private/Partials/'; + /** * @var \TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository */ @@ -262,40 +267,8 @@ class BackendController // Prepare the scaffolding, at this point extension may still add javascript and css $view = $this->getFluidTemplateObject($this->templatePath . 'Backend/Main.html'); - // Extension Configuration to find the TYPO3 logo in the left corner - $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['backend'], ['allowed_classes' => false]); - $logoPath = ''; - if (!empty($extConf['backendLogo'])) { - $customBackendLogo = GeneralUtility::getFileAbsFileName($extConf['backendLogo']); - if (!empty($customBackendLogo)) { - $logoPath = $customBackendLogo; - } - } - // if no custom logo was set or the path is invalid, use the original one - if (empty($logoPath)) { - $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3_logo_orange.svg'); - $logoWidth = 22; - $logoHeight = 22; - } else { - // set width/height for custom logo - $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $logoPath); - $logoWidth = $imageInfo->getWidth() ?? '22'; - $logoHeight = $imageInfo->getHeight() ?? '22'; - - // High-resolution? - if (strpos($logoPath, '@2x.') !== false) { - $logoWidth /= 2; - $logoHeight /= 2; - } - } - - $view->assign('logoUrl', PathUtility::getAbsoluteWebPath($logoPath)); - $view->assign('logoWidth', $logoWidth); - $view->assign('logoHeight', $logoHeight); - $view->assign('applicationVersion', TYPO3_version); - $view->assign('siteName', $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']); $view->assign('moduleMenu', $this->generateModuleMenu()); - $view->assign('toolbar', $this->renderToolbar()); + $view->assign('topbar', $this->renderTopbar()); /****************************************************** * Now put the complete backend document together @@ -342,6 +315,52 @@ class BackendController $this->executeHook('renderPostProcess', $hookConfiguration); } + /** + * Renders the topbar, containing the backend logo, sitename etc. + * + * @return string + */ + protected function renderTopbar() + { + $view = $this->getFluidTemplateObject($this->partialPath . 'Backend/Topbar.html'); + + // Extension Configuration to find the TYPO3 logo in the left corner + $extConf = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['backend'], ['allowed_classes' => false]); + $logoPath = ''; + if (!empty($extConf['backendLogo'])) { + $customBackendLogo = GeneralUtility::getFileAbsFileName($extConf['backendLogo']); + if (!empty($customBackendLogo)) { + $logoPath = $customBackendLogo; + } + } + // if no custom logo was set or the path is invalid, use the original one + if (empty($logoPath)) { + $logoPath = GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Public/Images/typo3_logo_orange.svg'); + $logoWidth = 22; + $logoHeight = 22; + } else { + // set width/height for custom logo + $imageInfo = GeneralUtility::makeInstance(ImageInfo::class, $logoPath); + $logoWidth = $imageInfo->getWidth() ?? '22'; + $logoHeight = $imageInfo->getHeight() ?? '22'; + + // High-resolution? + if (strpos($logoPath, '@2x.') !== false) { + $logoWidth /= 2; + $logoHeight /= 2; + } + } + + $view->assign('logoUrl', PathUtility::getAbsoluteWebPath($logoPath)); + $view->assign('logoWidth', $logoWidth); + $view->assign('logoHeight', $logoHeight); + $view->assign('applicationVersion', TYPO3_version); + $view->assign('siteName', $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename']); + $view->assign('toolbar', $this->renderToolbar()); + + return $view->render(); + } + /** * Loads the css and javascript files of all registered navigation widgets * @@ -836,6 +855,19 @@ class BackendController return $response; } + /** + * Returns the toolbar for the AJAX request + * + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @return ResponseInterface + */ + public function getTopbar(ServerRequestInterface $request, ResponseInterface $response) + { + $response->getBody()->write(json_encode(['topbar' => $this->renderTopbar()])); + return $response; + } + /** * returns a new standalone view, shorthand function * @@ -845,6 +877,7 @@ class BackendController protected function getFluidTemplateObject($templatePathAndFileName = null) { $view = GeneralUtility::makeInstance(StandaloneView::class); + $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]); if ($templatePathAndFileName) { $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFileName)); } diff --git a/typo3/sysext/backend/Classes/Utility/BackendUtility.php b/typo3/sysext/backend/Classes/Utility/BackendUtility.php index f52e8b075b056c6c1b59b5df165fb5350721352d..e7b4dc2d132d4fc8cda22a1fc525362a204a6807 100644 --- a/typo3/sysext/backend/Classes/Utility/BackendUtility.php +++ b/typo3/sysext/backend/Classes/Utility/BackendUtility.php @@ -3533,6 +3533,13 @@ class BackendUtility if (top && top.TYPO3.ModuleMenu && top.TYPO3.ModuleMenu.App) { top.TYPO3.ModuleMenu.App.refreshMenu(); }'; + break; + case 'updateTopbar': + $signals[] = ' + if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) { + top.TYPO3.Backend.Topbar.refresh(); + }'; + break; } } } diff --git a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php index 2ee8bd2ff88ba2591addc568516269512bad5933..b8a874752141cbe4544f9b3cdd4c78e9d6ceebfc 100644 --- a/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php +++ b/typo3/sysext/backend/Configuration/Backend/AjaxRoutes.php @@ -111,6 +111,10 @@ return [ 'path' => '/module-menu', 'target' => Controller\BackendController::class . '::getModuleMenu' ], + 'topbar' => [ + 'path' => '/topbar', + 'target' => Controller\BackendController::class . '::getTopbar' + ], // Log in into backend 'login' => [ diff --git a/typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html b/typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html new file mode 100644 index 0000000000000000000000000000000000000000..74ccfe20906976f7fc60a047ac7616ef14599b4e --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Partials/Backend/Topbar.html @@ -0,0 +1,37 @@ +{namespace core = TYPO3\CMS\Core\ViewHelpers} +<div class="scaffold-topbar t3js-scaffold-topbar"> + <div class="topbar"> + <div class="topbar-header t3js-topbar-header"> + <button class="topbar-button topbar-button-modulemenu t3js-topbar-button-modulemenu"> + <core:icon identifier="actions-move-move" alternativeMarkupIdentifier="inline" /> + </button> + <button class="topbar-button topbar-button-navigationcomponent t3js-topbar-button-navigationcomponent"> + <core:icon identifier="apps-pagetree-category-collapse-all" alternativeMarkupIdentifier="inline" /> + </button> + <div class="topbar-header-site"> + <a href="./" target="_top" title="{siteName} - {applicationVersion}"> + <span class="topbar-header-site-logo"> + <img src="{logoUrl}" width="{logoWidth}" height="{logoHeight}" title="TYPO3 Content Management System" alt="" /> + </span> + <span class="topbar-header-site-title"> + <span class="topbar-header-site-name">{siteName}</span> + <span class="topbar-header-site-version">{applicationVersion}</span> + </span> + </a> + </div> + <button class="topbar-button topbar-button-toolbar t3js-topbar-button-toolbar"> + <core:icon identifier="actions-system-extension-configure" alternativeMarkupIdentifier="inline" /> + </button> + <button class="topbar-button topbar-button-search t3js-topbar-button-search"> + <core:icon identifier="actions-search" alternativeMarkupIdentifier="inline" /> + </button> + </div> + </div> +</div> +<div class="scaffold-toolbar t3js-scaffold-toolbar"> + <div class="toolbar t3js-topbar-toolbar"> + <ul class="toolbar-list" data-typo3-role="typo3-module-menu"> + <f:format.raw>{toolbar}</f:format.raw> + </ul> + </div> +</div> \ No newline at end of file diff --git a/typo3/sysext/backend/Resources/Private/Templates/Backend/Main.html b/typo3/sysext/backend/Resources/Private/Templates/Backend/Main.html index 4e9132bdd84ca3841f241d987cbf613a16fe3b0f..3f8f8d1bbc1a0ceccae49077d30c4b5268fed42e 100644 --- a/typo3/sysext/backend/Resources/Private/Templates/Backend/Main.html +++ b/typo3/sysext/backend/Resources/Private/Templates/Backend/Main.html @@ -1,48 +1,12 @@ -{namespace core = TYPO3\CMS\Core\ViewHelpers} <div class="scaffold t3js-scaffold scaffold-modulemenu-expanded"> - <div class="scaffold-topbar t3js-scaffold-topbar"> - - <div class="topbar"> - <div class="topbar-header t3js-topbar-header"> - <button class="topbar-button topbar-button-modulemenu t3js-topbar-button-modulemenu"> - <core:icon identifier="actions-move-move" alternativeMarkupIdentifier="inline" /> - </button> - <button class="topbar-button topbar-button-navigationcomponent t3js-topbar-button-navigationcomponent"> - <core:icon identifier="apps-pagetree-category-collapse-all" alternativeMarkupIdentifier="inline" /> - </button> - <div class="topbar-header-site"> - <a href="./" target="_top" title="{siteName} - {applicationVersion}"> - <span class="topbar-header-site-logo"> - <img src="{logoUrl}" width="{logoWidth}" height="{logoHeight}" title="TYPO3 Content Management System" alt="" /> - </span> - <span class="topbar-header-site-title"> - <span class="topbar-header-site-name">{siteName}</span> - <span class="topbar-header-site-version">{applicationVersion}</span> - </span> - </a> - </div> - <button class="topbar-button topbar-button-toolbar t3js-topbar-button-toolbar"> - <core:icon identifier="actions-system-extension-configure" alternativeMarkupIdentifier="inline" /> - </button> - <button class="topbar-button topbar-button-search t3js-topbar-button-search"> - <core:icon identifier="actions-search" alternativeMarkupIdentifier="inline" /> - </button> - </div> - </div> - + <div class="t3js-scaffold-header"> + <f:format.raw>{topbar}</f:format.raw> </div> <div class="scaffold-modulemenu t3js-scaffold-modulemenu"> <div class="modulemenu t3js-modulemenu"> <f:format.raw>{moduleMenu}</f:format.raw> </div> </div> - <div class="scaffold-toolbar t3js-scaffold-toolbar"> - <div class="toolbar t3js-topbar-toolbar"> - <ul class="toolbar-list" data-typo3-role="typo3-module-menu"> - <f:format.raw>{toolbar}</f:format.raw> - </ul> - </div> - </div> <div class="scaffold-content t3js-scaffold-content"> <div class="scaffold-content-navigation t3js-scaffold-content-navigation"> <div class="scaffold-content-navigation-component" data-component="typo3-navigationIframe"> diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js b/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js index 32d8cee916e33475bb2e3a07dd8f28a87845eaa7..9ef0d2b5140f2e89266867e042cbe8d5d7e641f0 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/LiveSearch.js @@ -16,7 +16,12 @@ * Global search to deal with everything in the backend that is search-related * @exports TYPO3/CMS/Backend/LiveSearch */ -define(['jquery', 'jquery/autocomplete', 'TYPO3/CMS/Backend/jquery.clearable'], function ($) { +define([ + 'jquery', + 'TYPO3/CMS/Backend/Viewport', + 'jquery/autocomplete', + 'TYPO3/CMS/Backend/jquery.clearable' +], function ($, Viewport) { 'use strict'; var containerSelector = '#typo3-cms-backend-backend-toolbaritems-livesearchtoolbaritem'; @@ -28,7 +33,7 @@ define(['jquery', 'jquery/autocomplete', 'TYPO3/CMS/Backend/jquery.clearable'], var url = TYPO3.settings.ajaxUrls['livesearch']; var category = ''; - $(function() { + Viewport.Topbar.Toolbar.registerEvent(function() { $(searchFieldSelector).autocomplete({ // ajax options serviceUrl: url, diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ClearCacheMenu.js b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ClearCacheMenu.js index 22558fa61e5e415d01e80dfe1561f4402a1cc89d..66041556d73fdb8d89f8903d8450d629e9a34cdb 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ClearCacheMenu.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ClearCacheMenu.js @@ -16,7 +16,12 @@ * main functionality for clearing caches via the top bar * reloading the clear cache icon */ -define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Notification'], function($, Icons, Notification) { +define([ + 'jquery', + 'TYPO3/CMS/Backend/Icons', + 'TYPO3/CMS/Backend/Notification', + 'TYPO3/CMS/Backend/Viewport' +], function($, Icons, Notification, Viewport) { 'use strict'; /** @@ -76,7 +81,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Notification'], }); }; - $(ClearCacheMenu.initializeEvents); + Viewport.Topbar.Toolbar.registerEvent(ClearCacheMenu.initializeEvents); return ClearCacheMenu; }); diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ShortcutMenu.js b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ShortcutMenu.js index 91145a99221938474e629a06c786f682a3c5142c..a9da605d7ec497101f711e090a9a9b2b5b68ffd6 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ShortcutMenu.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/ShortcutMenu.js @@ -19,8 +19,9 @@ define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Icons', - 'TYPO3/CMS/Backend/Notification' - ], function($, Modal, Icons, Notification) { + 'TYPO3/CMS/Backend/Notification', + 'TYPO3/CMS/Backend/Viewport' + ], function($, Modal, Icons, Notification, Viewport) { 'use strict'; /** @@ -210,7 +211,7 @@ define(['jquery', }); }; - $(ShortcutMenu.initializeEvents); + Viewport.Topbar.Toolbar.registerEvent(ShortcutMenu.initializeEvents); // expose as global object TYPO3.ShortcutMenu = ShortcutMenu; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/SystemInformationMenu.js b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/SystemInformationMenu.js index bf03794c4110f83fba2ce3108fcfcc41baac803a..b3bb52e8d14bc1cb47efd3c1a5bfffc7f7127ad1 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/SystemInformationMenu.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/Toolbar/SystemInformationMenu.js @@ -15,7 +15,12 @@ * Module: TYPO3/CMS/Backend/Toolbar/SystemInformationMenu * System information menu handler */ -define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], function($, Icons, Storage) { +define([ + 'jquery', + 'TYPO3/CMS/Backend/Icons', + 'TYPO3/CMS/Backend/Storage', + 'TYPO3/CMS/Backend/Viewport' +], function($, Icons, Storage, Viewport) { 'use strict'; /** @@ -28,10 +33,8 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct containerSelector: '#typo3-cms-backend-backend-toolbaritems-systeminformationtoolbaritem', toolbarIconSelector: '.toolbar-item-icon .t3js-icon', menuContainerSelector: '.dropdown-menu', - moduleLinks: '.t3js-systeminformation-module' - }, - elements: { - $counter: $('.t3js-systeminformation-counter') + moduleLinks: '.t3js-systeminformation-module', + counter: '.t3js-systeminformation-counter' } }; @@ -78,14 +81,15 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct */ SystemInformationMenu.updateCounter = function() { var $container = $(SystemInformationMenu.identifier.containerSelector).find(SystemInformationMenu.identifier.menuContainerSelector).find('.t3js-systeminformation-container'), + $counter = $(SystemInformationMenu.identifier.counter), count = $container.data('count'), badgeClass = $container.data('severityclass'); - SystemInformationMenu.elements.$counter.text(count).toggle(parseInt(count) > 0); - SystemInformationMenu.elements.$counter.removeClass(); + $counter.text(count).toggle(parseInt(count) > 0); + $counter.removeClass(); if (badgeClass !== '') { - SystemInformationMenu.elements.$counter.addClass('toolbar-item-badge badge ' + badgeClass); + $counter.addClass('toolbar-item-badge badge ' + badgeClass); } }; @@ -113,11 +117,11 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons', 'TYPO3/CMS/Backend/Storage'], funct $ajax.done(function() { // finally, open the module now TYPO3.ModuleMenu.App.showModule(requestedModule); - SystemInformationMenu.updateMenu(); + Viewport.Topbar.refresh(); }); }; - $(SystemInformationMenu.updateMenu); + Viewport.Topbar.Toolbar.registerEvent(SystemInformationMenu.updateMenu); return SystemInformationMenu; }); diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/Viewport.js b/typo3/sysext/backend/Resources/Public/JavaScript/Viewport.js index 797f4653ae9ca4a6c2b8270ee791b6e9f1b585b0..75382df1f4b4a3d06fc69bfa614d1441160013e5 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/Viewport.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/Viewport.js @@ -142,6 +142,21 @@ define( return 0; } } + }, + Topbar: { + topbarSelector: '.t3js-scaffold-header', + refresh: function() { + $.ajax(TYPO3.settings.ajaxUrls['topbar']).done(function(data) { + $(TYPO3.Backend.Topbar.topbarSelector).html(data.topbar); + $(TYPO3.Backend.Topbar.topbarSelector).trigger('t3-topbar-update'); + }); + }, + Toolbar: { + registerEvent: function (callback) { + $(callback); + $(TYPO3.Backend.Topbar.topbarSelector).on('t3-topbar-update', callback); + } + } } }; diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst new file mode 100644 index 0000000000000000000000000000000000000000..96215609c7570b021064fc8001c49f7ac140e4fc --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-79196-ToolbarItemEventHandlingChanged.rst @@ -0,0 +1,45 @@ +.. include:: ../../Includes.txt + +====================================================== +Breaking: #79196 - Toolbar item event handling changed +====================================================== + +See :issue:`79196` + +Description +=========== + +With the introduction of the topbar reloading mechanism, the event handling of toolbar items has changed. Reason is +that the event information gets lost, as the whole topbar is rendered from scratch after a reload. + + +Impact +====== + +After reloading the topbar, not migrated events will not get triggered anymore. + + +Affected Installations +====================== + +All installations with old-fashioned toolbar item registrations are affected. + + +Migration +========= + +In most cases it's sufficient to replace the register function with `Viewport.Topbar.Toolbar.registerEvent()`. + +Example: + +.. code-block:: javascript + + define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) { + // old registration + $(MyAwesomeItem.doStuff) + + // new registration + Viewport.Topbar.Toolbar.registerEvent(MyAwesomeItem.doStuff); + }); + +.. index:: Backend, JavaScript \ No newline at end of file diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst new file mode 100644 index 0000000000000000000000000000000000000000..dc8f5e70eabc3e73120d856822964670e9abf8e0 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Feature-79196-AllowReloadOfTopbar.rst @@ -0,0 +1,51 @@ +.. include:: ../../Includes.txt + +======================================== +Feature: #79196 - Allow reload of topbar +======================================== + +See :issue:`79196` + +Description +=========== + +A new JavaScript API to reload the backend's topbar has been introduced to the TYPO3 Core. + + +Impact +====== + +The toolbar reloading may be triggered on JavaScript and PHP code level. To enforce the reloading on PHP side, +call :php:`\TYPO3\CMS\Backend\Utility\BackendUtility::setUpdateSignal('updateTopbar')`. + +Reloading the topbar via JavaScript requires the following code: + +.. code-block:: javascript + + // Either: RequireJS style + define(['TYPO3/CMS/Backend/Viewport'], function(Viewport) { + Viewport.Topbar.refresh(); + }); + + // Or: old-fashioned JavaScript + if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) { + top.TYPO3.Backend.Topbar.refresh(); + }'; + + +In case a toolbar item registers to the `load` event of the page, the registration must be changed. Reason is that the +event information gets lost, as the whole toolbar is rendered from scratch after a reload. + +Example: + +.. code-block:: javascript + + define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) { + // old registration + $(MyAwesomeItem.doStuff) + + // new registration + Viewport.Topbar.Toolbar.registerEvent(MyAwesomeItem.doStuff); + }); + +.. index:: Backend, JavaScript, PHP-API \ No newline at end of file diff --git a/typo3/sysext/extensionmanager/Classes/Controller/AbstractController.php b/typo3/sysext/extensionmanager/Classes/Controller/AbstractController.php index 2ff223e3bfdcd0f5c5c12f186e3f6dd8eb23b9ab..017ac8d9dcd33518fba2f585f3046b0f4313e9c4 100644 --- a/typo3/sysext/extensionmanager/Classes/Controller/AbstractController.php +++ b/typo3/sysext/extensionmanager/Classes/Controller/AbstractController.php @@ -21,11 +21,14 @@ class AbstractController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionControl { const TRIGGER_RefreshModuleMenu = 'refreshModuleMenu'; + const TRIGGER_RefreshTopbar = 'refreshTopbar'; + /** * @var array */ protected $triggerArguments = [ self::TRIGGER_RefreshModuleMenu, + self::TRIGGER_RefreshTopbar ]; /** diff --git a/typo3/sysext/extensionmanager/Classes/Controller/ActionController.php b/typo3/sysext/extensionmanager/Classes/Controller/ActionController.php index 97095620658b8f55d2d110d40134f2a1d0b5d32a..fa16187010f7983e2846848c29048184bfadf036 100644 --- a/typo3/sysext/extensionmanager/Classes/Controller/ActionController.php +++ b/typo3/sysext/extensionmanager/Classes/Controller/ActionController.php @@ -98,7 +98,10 @@ class ActionController extends AbstractController } catch (\TYPO3\CMS\Core\Package\Exception\PackageStatesFileNotWritableException $e) { $this->addFlashMessage($e->getMessage(), '', \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR); } - $this->redirect('index', 'List', null, [self::TRIGGER_RefreshModuleMenu => true]); + $this->redirect('index', 'List', null, [ + self::TRIGGER_RefreshModuleMenu => true, + self::TRIGGER_RefreshTopbar => true + ]); } /** diff --git a/typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php b/typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php index cb511ea34e5ce00efd2daed5af7355e803aed3d6..9e6394874d67134d31d3321a09f53f0e1bd002e3 100644 --- a/typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php +++ b/typo3/sysext/extensionmanager/Classes/Controller/ConfigurationController.php @@ -81,6 +81,8 @@ class ConfigurationController extends AbstractModuleController if (!isset($extension['key'])) { throw new ExtensionManagerException('Extension key not found.', 1359206803); } + $this->handleTriggerArguments(); + $extKey = $extension['key']; $configuration = $this->configurationItemRepository->findByExtensionKey($extKey); if ($configuration) { @@ -117,7 +119,12 @@ class ConfigurationController extends AbstractModuleController ) { $this->redirect('welcome', 'Distribution', null, ['extension' => $extension->getUid()]); } else { - $this->redirect('showConfigurationForm', null, null, ['extension' => ['key' => $extensionKey]]); + $this->redirect('showConfigurationForm', null, null, [ + 'extension' => [ + 'key' => $extensionKey + ], + self::TRIGGER_RefreshTopbar => true + ]); } } @@ -131,7 +138,9 @@ class ConfigurationController extends AbstractModuleController public function saveAndCloseAction(array $config, $extensionKey) { $this->saveConfiguration($config, $extensionKey); - $this->redirect('index', 'List'); + $this->redirect('index', 'List', null, [ + self::TRIGGER_RefreshTopbar => true + ]); } /** diff --git a/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php b/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php index 64fabba6ec43da92ad6ddbc8598702e9f69f1179..cb53d8f584dcdd932aa0e4f35ee938bd465464cb 100644 --- a/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php +++ b/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php @@ -179,7 +179,10 @@ class UploadExtensionFileController extends AbstractController $this->removeExtensionAndRestoreFromBackup($fileName); $this->addFlashMessage($exception->getMessage(), '', FlashMessage::ERROR); } - $this->redirect('index', 'List', null, [self::TRIGGER_RefreshModuleMenu => true]); + $this->redirect('index', 'List', null, [ + self::TRIGGER_RefreshModuleMenu => true, + self::TRIGGER_RefreshTopbar => true + ]); } /** diff --git a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php index e09512bef4130f3be4854e386fbaa66a1c51afd8..11a2af7974ba7de0f2a2fec72b7a10a6a443993d 100644 --- a/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php +++ b/typo3/sysext/extensionmanager/Classes/ViewHelpers/Be/TriggerViewHelper.php @@ -60,6 +60,13 @@ class TriggerViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Be\AbstractBackendV 'if (top && top.TYPO3.ModuleMenu.App) { top.TYPO3.ModuleMenu.App.refreshMenu(); }' ); } + + if (!empty($this->arguments['triggers'][AbstractController::TRIGGER_RefreshTopbar])) { + $pageRenderer->addJsInlineCode( + AbstractController::TRIGGER_RefreshTopbar, + 'if (top && top.TYPO3.Backend && top.TYPO3.Backend.Topbar) { top.TYPO3.Backend.Topbar.refresh(); }' + ); + } return ''; } } diff --git a/typo3/sysext/opendocs/Resources/Public/JavaScript/Toolbar/OpendocsMenu.js b/typo3/sysext/opendocs/Resources/Public/JavaScript/Toolbar/OpendocsMenu.js index da228a78fd42dd0148607be99db10a8b61739346..a690a23bf46d82e4e42b67c760eea563a41a93c0 100644 --- a/typo3/sysext/opendocs/Resources/Public/JavaScript/Toolbar/OpendocsMenu.js +++ b/typo3/sysext/opendocs/Resources/Public/JavaScript/Toolbar/OpendocsMenu.js @@ -17,7 +17,11 @@ * - navigating to the documents * - updating the menu */ -define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) { +define([ + 'jquery', + 'TYPO3/CMS/Backend/Icons', + 'TYPO3/CMS/Backend/Viewport' +], function($, Icons, Viewport) { 'use strict'; /** @@ -113,7 +117,7 @@ define(['jquery', 'TYPO3/CMS/Backend/Icons'], function($, Icons) { $(OpendocsMenu.options.containerSelector).toggleClass('open'); }; - $(function() { + Viewport.Topbar.Toolbar.registerEvent(function() { OpendocsMenu.initializeEvents(); OpendocsMenu.updateMenu(); }); diff --git a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php index 71d4d6c423286e9816b3fd1cb7e38a15e5fb8298..fbf0d7c64718ed41cd6e2dde56e951b069f40bf3 100644 --- a/typo3/sysext/setup/Classes/Controller/SetupModuleController.php +++ b/typo3/sysext/setup/Classes/Controller/SetupModuleController.php @@ -299,6 +299,8 @@ class SetupModuleController extends AbstractModule } // Restore admin status after processing $beUser->user['admin'] = $isAdmin; + + BackendUtility::setUpdateSignal('updateTopbar'); } } } diff --git a/typo3/sysext/workspaces/Resources/Public/JavaScript/Toolbar/WorkspacesMenu.js b/typo3/sysext/workspaces/Resources/Public/JavaScript/Toolbar/WorkspacesMenu.js index 2a57f0dc2440056c76b96981658eec44a68c79c5..c73d780a59469b67459037180a1f70faae1f2cbd 100644 --- a/typo3/sysext/workspaces/Resources/Public/JavaScript/Toolbar/WorkspacesMenu.js +++ b/typo3/sysext/workspaces/Resources/Public/JavaScript/Toolbar/WorkspacesMenu.js @@ -16,7 +16,7 @@ * toolbar menu for the workspaces functionality to switch between the workspaces * and jump to the workspaces module */ -define(['jquery'], function($) { +define(['jquery', 'TYPO3/CMS/Backend/Viewport'], function($, Viewport) { 'use strict'; /** @@ -160,7 +160,7 @@ define(['jquery'], function($) { } }; - $(function() { + Viewport.Topbar.Toolbar.registerEvent(function() { WorkspacesMenu.initializeEvents(); WorkspacesMenu.updateBackendContext(); });