diff --git a/Build/tsconfig.json b/Build/tsconfig.json index 12ad7584ff93..c0eeae87b7e9 100644 --- a/Build/tsconfig.json +++ b/Build/tsconfig.json @@ -50,10 +50,6 @@ "../typo3/sysext/install/Resources/Public/JavaScript/*", "../typo3/sysext/install/Resources/Private/TypeScript/*" ], - "TYPO3/CMS/Lang/*": [ - "../typo3/sysext/lang/Resources/Public/JavaScript/*", - "../typo3/sysext/lang/Resources/Private/TypeScript/*" - ], "TYPO3/CMS/Linkvalidator/*": [ "../typo3/sysext/linkvalidator/Resources/Public/JavaScript/*", "../typo3/sysext/linkvalidator/Resources/Private/TypeScript/*" diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTreeToolbar.js b/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTreeToolbar.js index 826f890fb196..2f4d7b762847 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTreeToolbar.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/PageTree/PageTreeToolbar.js @@ -19,8 +19,7 @@ define(['jquery', 'd3', 'TYPO3/CMS/Backend/PageTree/PageTreeDragDrop', 'TYPO3/CMS/Backend/Tooltip', - 'TYPO3/CMS/Backend/SvgTree', - 'TYPO3/CMS/Lang/Lang' + 'TYPO3/CMS/Backend/SvgTree' ], function($, Icons, d3, PageTreeDragDrop) { 'use strict'; diff --git a/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js b/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js index c74feb40b4f3..f3232ee5b7e1 100644 --- a/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js +++ b/typo3/sysext/backend/Resources/Public/JavaScript/SvgTree.js @@ -22,8 +22,7 @@ define( 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'TYPO3/CMS/Backend/Notification', - 'TYPO3/CMS/Backend/Icons', - 'TYPO3/CMS/Lang/Lang' + 'TYPO3/CMS/Backend/Icons' ], function($, d3, ContextMenu, Modal, Severity, Notification, Icons) { 'use strict'; diff --git a/typo3/sysext/core/Classes/Page/PageRenderer.php b/typo3/sysext/core/Classes/Page/PageRenderer.php index 41d9792dfeb9..1fa9f069cd40 100644 --- a/typo3/sysext/core/Classes/Page/PageRenderer.php +++ b/typo3/sysext/core/Classes/Page/PageRenderer.php @@ -1887,22 +1887,46 @@ protected function renderMainJavaScriptLibraries() if (TYPO3_MODE === 'BE') { $this->addAjaxUrlsToInlineSettings(); } - $inlineSettings = $this->inlineLanguageLabels ? 'TYPO3.lang = ' . json_encode($this->inlineLanguageLabels) . ';' : ''; + $inlineSettings = ''; + $languageLabels = $this->parseLanguageLabelsForJavaScript(); + if (!empty($languageLabels)) { + $inlineSettings .= 'TYPO3.lang = ' . json_encode($languageLabels) . ';'; + } $inlineSettings .= $this->inlineSettings ? 'TYPO3.settings = ' . json_encode($this->inlineSettings) . ';' : ''; if ($inlineSettings !== '') { // make sure the global TYPO3 is available $inlineSettings = 'var TYPO3 = TYPO3 || {};' . CRLF . $inlineSettings; $out .= $this->inlineJavascriptWrap[0] . $inlineSettings . $this->inlineJavascriptWrap[1]; - // Add language module only if also jquery is guaranteed to be there - if (TYPO3_MODE === 'BE' && !empty($this->jQueryVersions)) { - $this->loadRequireJsModule('TYPO3/CMS/Lang/Lang'); - } } return $out; } + /** + * Converts the language labels for usage in JavaScript + * + * @return array + */ + protected function parseLanguageLabelsForJavaScript(): array + { + if (empty($this->inlineLanguageLabels)) { + return []; + } + + $labels = []; + foreach ($this->inlineLanguageLabels as $key => $translationUnit) { + if (is_array($translationUnit)) { + $translationUnit = current($translationUnit); + $labels[$key] = $translationUnit['target'] ?? $translationUnit['source']; + } else { + $labels[$key] = $translationUnit; + } + } + + return $labels; + } + /** * Load the language strings into JavaScript */ diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-84148-RequireJSModuleForLanguageHandlingRemoved.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-84148-RequireJSModuleForLanguageHandlingRemoved.rst new file mode 100644 index 000000000000..ee55d965aac8 --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/master/Breaking-84148-RequireJSModuleForLanguageHandlingRemoved.rst @@ -0,0 +1,33 @@ +.. include:: ../../Includes.txt + +================================================================= +Breaking: #84148 - RequireJS module for language handling removed +================================================================= + +See :issue:`84148` + +Description +=========== + +Since the removal of ExtJS, the JavaScript files that handle the localization of labels in backend modules became obsolete and are removed. + + +Impact +====== + +Depending on the RequireJS module :js:`TYPO3/CMS/Lang/Lang` will result in `404` errors, as the module has been removed. + + +Affected Installations +====================== + +Every 3rd party extension depending on :js:`TYPO3/CMS/Lang/Lang` is affected. + + +Migration +========= + +Remove the module from the affected RequireJS modules. The labels are now prepared by the PageRenderer and passed +to :js:`TYPO3.lang` without the need of additional JavaScript. + +.. index:: Backend, JavaScript, NotScanned diff --git a/typo3/sysext/core/Tests/Unit/Page/PageRendererTest.php b/typo3/sysext/core/Tests/Unit/Page/PageRendererTest.php index 9aa67d382f5a..90fe3d02ae85 100644 --- a/typo3/sysext/core/Tests/Unit/Page/PageRendererTest.php +++ b/typo3/sysext/core/Tests/Unit/Page/PageRendererTest.php @@ -311,4 +311,48 @@ public function unsetAddedMetaTag() $expectedResult = []; $this->assertSame($expectedResult, $actualResult); } + + /** + * @test + */ + public function parseLanguageLabelsForJavaScriptReturnsEmptyStringIfEmpty() + { + $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Page\PageRenderer::class, ['dummy'], [], '', false); + $inlineLanguageLabels = []; + $subject->_set('inlineLanguageLabels', $inlineLanguageLabels); + $actual = $subject->_call('parseLanguageLabelsForJavaScript'); + $this->assertEmpty($actual); + } + + /** + * @test + */ + public function parseLanguageLabelsForJavaScriptReturnsFlatArray() + { + $subject = $this->getAccessibleMock(\TYPO3\CMS\Core\Page\PageRenderer::class, ['dummy'], [], '', false); + $inlineLanguageLabels = [ + 'key' => 'label', + 'foo' => 'bar', + 'husel' => [ + [ + 'source' => 'pusel', + ] + ], + 'hello' => [ + [ + 'source' => 'world', + 'target' => 'welt', + ] + ], + ]; + $subject->_set('inlineLanguageLabels', $inlineLanguageLabels); + $expected = [ + 'key' => 'label', + 'foo' => 'bar', + 'husel' => 'pusel', + 'hello' => 'welt', + ]; + $actual = $subject->_call('parseLanguageLabelsForJavaScript'); + $this->assertSame($expected, $actual); + } } diff --git a/typo3/sysext/lang/Resources/Public/JavaScript/Lang.js b/typo3/sysext/lang/Resources/Public/JavaScript/Lang.js deleted file mode 100644 index 0f13c0784322..000000000000 --- a/typo3/sysext/lang/Resources/Public/JavaScript/Lang.js +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -/** - * Module: TYPO3/CMS/Lang/Lang - * Transforms the TYPO3.lang object into a flat object - * - * `TYPO3.lang.foo[0].target = 'blah'` becomes `TYPO3.lang['foo'] = 'blah'` - */ -define(['jquery'], function($) { - /** - * - * @type {{}} - * @exports TYPO3/CMS/Lang/Lang - */ - var Lang = {}; - - /** - * - */ - Lang.convertToOneDimension = function() { - var originalLangObject = $.extend(true, {}, TYPO3.lang); - TYPO3.lang = []; - $.each(originalLangObject, function(index, value) { - if (typeof value === "object") { - TYPO3.lang[index] = value[0].target || value[0].source; - } else { - TYPO3.lang[index] = value; - } - }); - - delete originalLangObject; - }; - - Lang.convertToOneDimension(); - return TYPO3.lang; -}); diff --git a/typo3/sysext/lang/Resources/Public/JavaScript/Typo3Lang.js b/typo3/sysext/lang/Resources/Public/JavaScript/Typo3Lang.js deleted file mode 100644 index 9f130f451c7e..000000000000 --- a/typo3/sysext/lang/Resources/Public/JavaScript/Typo3Lang.js +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the TYPO3 CMS project. - * - * It is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, either version 2 - * of the License, or any later version. - * - * For the full copyright and license information, please read the - * LICENSE.txt file that was distributed with this source code. - * - * The TYPO3 project - inspiring people to share! - */ - -Ext.ns('TYPO3.l10n'); - -TYPO3.l10n = function() { - - /** - * Protected copy of translationUnits - * @private - */ - var lang = [], - - sanitize = function() { - if (typeof TYPO3.lang !== 'undefined') { - for (key in TYPO3.lang) { - lang[key] = TYPO3.lang[key]; - - if (!Ext.isString(TYPO3.lang[key])) { - TYPO3.lang[key] = TYPO3.lang[key][0].target; - } - } - } - }; - - return { - - initialize: function() { - sanitize(); - }, - - localize: function(label, replace, plural) { - if (typeof lang === 'undefined' || typeof lang[label] === 'undefined') { - return false; - } - - var i = plural || 0, - translationUnit = lang[label], - label = null, regexp = null; - - // Get localized label - if (Ext.isString(translationUnit)) { - label = translationUnit; - } else { - label = translationUnit[i]['target']; - } - - // Replace - if (typeof replace !== 'undefined') { - for (key in replace) { - regexp = new RegExp('%' + key + '|%s'); - label = label.replace(regexp, replace[key]); - } - } - - return label; - } - }; -}(); - -TYPO3.l10n.initialize();