From 89a8146699b73896d1ca8869e43cd53f16e3bdfe Mon Sep 17 00:00:00 2001 From: Frank Naegler <frank.naegler@typo3.org> Date: Wed, 9 Nov 2016 14:04:37 +0100 Subject: [PATCH] [TASK] Streamline and optimize JavaScript in install tool This patch optimize and streamline the JavaScript of Install.js The following changes are part of the patch: - Centralized FlashMessage handling - Streamline server side and browser side severities - Optimize performance, remove duplicate jQuery selector - Remove console.debug calls - Remove unused FlashMessage templates from views Resolves: #78376 Releases: master, 7.6 Change-Id: I0652335e5d0bc4666896d5c7b6b528db445ee951 Reviewed-on: https://review.typo3.org/50553 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl> Tested-by: Wouter Wolters <typo3@wouterwolters.nl> Reviewed-by: Markus Klein <markus.klein@typo3.org> Tested-by: Markus Klein <markus.klein@typo3.org> --- .../sysext/install/Classes/View/JsonView.php | 38 +++- .../Partials/Action/Common/StatusMessage.html | 2 +- .../ImportantActions/CoreUpdateButton.html | 7 - .../ImportantActions/TcaExtTablesCheck.html | 8 +- .../ImportantActions/TcaMigrationsCheck.html | 8 +- .../Templates/Action/Tool/LoadExtensions.html | 7 +- .../Resources/Public/JavaScript/Install.js | 187 +++++++++--------- .../install/Tests/Unit/View/JsonViewTest.php | 4 +- 8 files changed, 142 insertions(+), 119 deletions(-) diff --git a/typo3/sysext/install/Classes/View/JsonView.php b/typo3/sysext/install/Classes/View/JsonView.php index b42bb3b31faf..8be2af179ef7 100644 --- a/typo3/sysext/install/Classes/View/JsonView.php +++ b/typo3/sysext/install/Classes/View/JsonView.php @@ -75,9 +75,45 @@ class JsonView extends AbstractView public function transformStatusToArray(StatusInterface $status) { $arrayStatus = []; - $arrayStatus['severity'] = htmlspecialchars($status->getSeverity()); + $arrayStatus['severity'] = $this->getSeverityAsNumber($status->getSeverity()); $arrayStatus['title'] = htmlspecialchars($status->getTitle()); $arrayStatus['message'] = htmlspecialchars($status->getMessage()); return $arrayStatus; } + + /** + * Return the corresponding integer value for given severity string + * + * @param string $severity + * + * @return int + */ + protected function getSeverityAsNumber($severity) + { + $number = -2; + switch (strtolower($severity)) { + case 'loading': + $number = -3; + break; + case 'notice': + $number = -2; + break; + case 'info': + $number = -1; + break; + case 'ok': + case 'success': + $number = 0; + break; + case 'warning': + $number = 1; + break; + case 'error': + case 'danger': + case 'fatal': + $number = 2; + break; + } + return $number; + } } diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Common/StatusMessage.html b/typo3/sysext/install/Resources/Private/Partials/Action/Common/StatusMessage.html index e215537cdfe3..8fc5867fd24e 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Action/Common/StatusMessage.html +++ b/typo3/sysext/install/Resources/Private/Partials/Action/Common/StatusMessage.html @@ -12,7 +12,7 @@ <div class="t3js-message typo3-message alert alert-info" role="alert"> </f:case> <f:case value="loading"> - <div class="t3js-message typo3-message alert alert-loading" role="alert"> + <div class="t3js-message typo3-message alert alert-notice alert-loading" role="alert"> </f:case> <f:case value=""> <div class="t3js-message typo3-message alert alert-notice" role="alert"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/CoreUpdateButton.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/CoreUpdateButton.html index 10d71fdab421..947ee209f75a 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/CoreUpdateButton.html +++ b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/CoreUpdateButton.html @@ -8,13 +8,6 @@ <div id="coreUpdate"> <f:if condition="{enableCoreUpdate}"> <f:then> - <div id="messageTemplate"> - <div class="t3js-message typo3-message alert"> - <h4></h4> - <p class="messageText"></p> - </div> - <p></p> - </div> <div id="buttonTemplate"> <fieldset class="t3-install-form-submit"> <button class="btn btn-default" type="submit" name="coreUpdateCheckForUpdate" data-action="checkForUpdate"> diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html index 1bfec807c19e..53bc2b728175 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html +++ b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaExtTablesCheck.html @@ -5,12 +5,6 @@ <form method="post"> <f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" /> <div id="tcaExtTablesCheck"> - <div class="messageTemplate" style="display: none;"> - <div class="t3js-message typo3-message alert"> - <h4></h4> - <p class="messageText"></p> - </div> - </div> <f:render partial="Action/Common/SubmitButton" arguments="{name:'tceExtTablesCheck', text:'Check loaded extensions'}"/> </div> -</form> \ No newline at end of file +</form> diff --git a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaMigrationsCheck.html b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaMigrationsCheck.html index 3130860f16a5..fe948c3d5786 100644 --- a/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaMigrationsCheck.html +++ b/typo3/sysext/install/Resources/Private/Partials/Action/Tool/ImportantActions/TcaMigrationsCheck.html @@ -5,12 +5,6 @@ <form method="post"> <f:render partial="Action/Common/HiddenFormFields" arguments="{_all}" /> <div id="tcaMigrationsCheck"> - <div class="messageTemplate" style="display: none;"> - <div class="t3js-message typo3-message alert"> - <h4></h4> - <p class="messageText"></p> - </div> - </div> <f:render partial="Action/Common/SubmitButton" arguments="{name:'tcaMigrationsCheck', text:'Check TCA Migrations'}"/> </div> -</form> \ No newline at end of file +</form> diff --git a/typo3/sysext/install/Resources/Private/Templates/Action/Tool/LoadExtensions.html b/typo3/sysext/install/Resources/Private/Templates/Action/Tool/LoadExtensions.html index d48498f12ff5..64353594c1b3 100644 --- a/typo3/sysext/install/Resources/Private/Templates/Action/Tool/LoadExtensions.html +++ b/typo3/sysext/install/Resources/Private/Templates/Action/Tool/LoadExtensions.html @@ -19,9 +19,10 @@ <f:render partial="Action/Tool/ImportantActions/ExtensionCompatibilityTester" arguments="{_all}"/> <script type="text/javascript"> $(function() { - $('button', '#checkExtensions').hide(); - $('.t3js-message', '#checkExtensions').hide(); - $('.t3js-message-loading', '#checkExtensions').show(); + var $container = $('#checkExtensions'); + $('button', $container).hide(); + $('.t3js-message', $container).hide(); + $('.t3js-message-loading', $container).show(); TYPO3.Install.ExtensionChecker.checkExtensionsCompatibility(true); }); </script> diff --git a/typo3/sysext/install/Resources/Public/JavaScript/Install.js b/typo3/sysext/install/Resources/Public/JavaScript/Install.js index 1f514d6b7d93..aaedfd044d8c 100644 --- a/typo3/sysext/install/Resources/Public/JavaScript/Install.js +++ b/typo3/sysext/install/Resources/Public/JavaScript/Install.js @@ -21,6 +21,57 @@ var TYPO3 = {}; TYPO3.Install = {}; +TYPO3.Install.Severity = { + loading: -3, + notice: -2, + info: -1, + ok: 0, + warning: 1, + error: 2 +}; + +TYPO3.Install.Severity.getCssClass = function(severity) { + var severityClass; + switch (severity) { + case TYPO3.Install.Severity.loading: + severityClass = 'notice alert-loading'; + break; + case TYPO3.Install.Severity.notice: + severityClass = 'notice'; + break; + case TYPO3.Install.Severity.ok: + severityClass = 'success'; + break; + case TYPO3.Install.Severity.warning: + severityClass = 'warning'; + break; + case TYPO3.Install.Severity.error: + severityClass = 'danger'; + break; + case TYPO3.Install.Severity.info: + default: + severityClass = 'info'; + } + return severityClass; +}; + +TYPO3.Install.FlashMessage = { + template: $('<div class="t3js-message typo3-message alert"><h4></h4><p class="messageText"></p></div>'), + render: function(severity, title, message) { + var flashMessage = this.template.clone(); + flashMessage.addClass('alert-' + TYPO3.Install.Severity.getCssClass(severity)); + if (title) { + flashMessage.find('h4').html(title); + } + if (message) { + flashMessage.find('.messageText').html(message); + } else { + flashMessage.find('.messageText').remove(); + } + return flashMessage; + } +}; + TYPO3.Install.Cache = { /** * Ajax call to clear all caches. @@ -75,6 +126,7 @@ TYPO3.Install.ExtensionChecker = { var self = this; var url = location.href + '&install[controller]=ajax&install[action]=uninstallExtension' + '&install[uninstallExtension][extensions]=' + extension; + var $container = $('#checkExtensions'); $.ajax({ url: url, cache: false, @@ -89,15 +141,18 @@ TYPO3.Install.ExtensionChecker = { if (data.substring(data.length - 2) === 'OK') { self.checkExtensionsCompatibility(true); } else { - $('.alert-loading', '#checkExtensions').hide(); - $('.alert-error .messageText', '#checkExtensions').html( - 'Something went wrong. Check failed.' + '<p>Message:<br />' + data + '</p>' + $('.alert-loading', $container).hide(); + var domMessage = TYPO3.Install.FlashMessage.render( + TYPO3.Install.Severity.error, + 'Something went wrong. Check failed.', + 'Message: ' + data ); + $container.append(domMessage); } } }, error: function(data) { - self.handleCheckExtensionsError(); + self.handleCheckExtensionsError(data); } }); }, @@ -114,7 +169,7 @@ TYPO3.Install.ExtensionChecker = { cache: false, success: function(data) { if (data) { - $('.alert-danger .messageText', '#checkExtensions').html( + $('.alert-danger .messageText', $checkExtensions).html( 'The following extensions are not compatible. Please uninstall them and try again. ' ); var extensions = data.split(','); @@ -127,7 +182,7 @@ TYPO3.Install.ExtensionChecker = { 'data-extension': $.trim(extension) }); var fullButton = unloadButtonWrapper.append(unloadButton); - $('.alert-danger .messageText', '#checkExtensions').append(fullButton); + $('.alert-danger .messageText', $checkExtensions).append(fullButton); } if (extensions.length) { $(document).on('click', 't3-js-uninstallSingle', function(e) { @@ -139,7 +194,7 @@ TYPO3.Install.ExtensionChecker = { var unloadAllButton = $('<button />', { text: 'Uninstall all incompatible extensions: ' + data, click: function(e) { - $('.alert-loading', '#checkExtensions').show(); + $('.alert-loading', $checkExtensions).show(); self.uninstallExtension(data); e.preventDefault(); return false; @@ -147,19 +202,19 @@ TYPO3.Install.ExtensionChecker = { }); unloadButtonWrapper.append('<hr />'); var fullUnloadAllButton = unloadButtonWrapper.append(unloadAllButton); - $('.alert-danger .messageText', '#checkExtensions').append(fullUnloadAllButton); + $('.alert-danger .messageText', $checkExtensions).append(fullUnloadAllButton); - $('.alert-loading', '#checkExtensions').hide(); - $('button', '#checkExtensions').show(); - $('.alert-danger', '#checkExtensions').show(); + $('.alert-loading', $checkExtensions).hide(); + $('button', $checkExtensions).show(); + $('.alert-danger', $checkExtensions).show(); } else { - $('.t3js-message', '#checkExtensions').hide(); - $('.alert-success', '#checkExtensions').show(); + $('.t3js-message', $checkExtensions).hide(); + $('.alert-success', $checkExtensions).show(); } }, error: function() { - $('.t3js-message', '#checkExtensions').hide(); - $('.alert-success', '#checkExtensions').show(); + $('.t3js-message', $checkExtensions).hide(); + $('.alert-success', $checkExtensions).show(); } }); $.getJSON( @@ -167,11 +222,8 @@ TYPO3.Install.ExtensionChecker = { function(data) { $.each(data, function(i, error) { var messageToDisplay = error.message + ' in ' + error.file + ' on line ' + error.line; - $checkExtensions.find('.t3js-message.alert-danger').before($( - '<div class="t3js-message alert-warning">' + - '<h4>' + error.type + '</h4><p class="messageText">' + - messageToDisplay + '</p></div><p></p>' - )); + var domMessage = TYPO3.Install.FlashMessage.render(TYPO3.Install.Severity.warning, error.type, messageToDisplay); + $checkExtensions.find('.t3js-message.alert-danger').before(domMessage); }); } ); @@ -248,11 +300,6 @@ TYPO3.Install.TcaIntegrityChecker = { */ outputContainer: {}, - /** - * Clone of a DOM object acts as message template - */ - messageTemplate: {}, - /** * Clone of the DOM object that contains the submit button */ @@ -276,13 +323,6 @@ TYPO3.Install.TcaIntegrityChecker = { // submitButton.remove(); } - // message template (for the output): save and delete - if(!this.messageTemplate[tcaIntegrityCheckContainer]) { - var messageTemplateSection = this.outputContainer[tcaIntegrityCheckContainer].find('.messageTemplate'); - this.messageTemplate[tcaIntegrityCheckContainer] = messageTemplateSection.children().clone().show(); - messageTemplateSection.remove(); - } - // clear all messages from the run before this.outputContainer[tcaIntegrityCheckContainer].find('.typo3-message:visible ').remove(); @@ -298,7 +338,7 @@ TYPO3.Install.TcaIntegrityChecker = { var isInitialized = self.initialize(actionName); if(isInitialized) { self.addMessage( - 'loading', + TYPO3.Install.Severity.loading, self.outputMessages[actionName].loadingTitle, self.outputMessages[actionName].loadingMessage, actionName @@ -313,12 +353,13 @@ TYPO3.Install.TcaIntegrityChecker = { if(data.status.length > 0) { self.outputContainer[actionName].find('.alert-loading').hide(); self.addMessage( - 'warning', + TYPO3.Install.Severity.warning, self.outputMessages[actionName].warningTitle, self.outputMessages[actionName].warningMessage, actionName ); data.status.forEach((function (element) { + //noinspection JSUnresolvedVariable self.addMessage( element.severity, element.title, @@ -330,7 +371,7 @@ TYPO3.Install.TcaIntegrityChecker = { // nothing to complain, everything fine self.outputContainer[actionName].find('.alert-loading').hide(); self.addMessage( - 'success', + TYPO3.Install.Severity.ok, self.outputMessages[actionName].successTitle, self.outputMessages[actionName].successMessage, actionName @@ -343,7 +384,7 @@ TYPO3.Install.TcaIntegrityChecker = { error: function() { self.outputContainer[actionName].find('.alert-loading').hide(); self.addMessage( - 'fatal', + TYPO3.Install.Severity.error, self.outputMessages[actionName].fatalTitle, self.outputMessages[actionName].fatalMessage, actionName @@ -359,8 +400,6 @@ TYPO3.Install.TcaIntegrityChecker = { * @param tcaIntegrityCheckContainer DOM container name */ moveSubmitButtonFurtherDown: function(tcaIntegrityCheckContainer) { - console.debug(this.outputContainer[tcaIntegrityCheckContainer], 'this.outputContainer['+[tcaIntegrityCheckContainer]+']'); - // first remove the currently visible button this.outputContainer[tcaIntegrityCheckContainer].find('button[type="submit"]').remove(); // then append the cloned template to the end @@ -376,18 +415,7 @@ TYPO3.Install.TcaIntegrityChecker = { * @param tcaIntegrityCheckContainer DOM container name */ addMessage: function(severity, title, message, tcaIntegrityCheckContainer) { - var domMessage = this.messageTemplate[tcaIntegrityCheckContainer].clone(); - if (severity) { - domMessage.addClass('alert-' + severity); - } - if (title) { - domMessage.find('h4').html(title); - } - if (message) { - domMessage.find('.messageText').html(message); - } else { - domMessage.find('.messageText').remove(); - } + var domMessage = TYPO3.Install.FlashMessage.render(severity, title, message); this.outputContainer[tcaIntegrityCheckContainer].append(domMessage); this.moveSubmitButtonFurtherDown(tcaIntegrityCheckContainer); } @@ -473,11 +501,6 @@ TYPO3.Install.coreUpdate = { } }, - /** - * Clone of a DOM object acts as message template - */ - messageTemplate: null, - /** * Clone of a DOM object acts as button template */ @@ -487,11 +510,8 @@ TYPO3.Install.coreUpdate = { * Fetching the templates out of the DOM */ initialize: function() { - var messageTemplateSection = $('#messageTemplate'); var buttonTemplateSection = $('#buttonTemplate'); - this.messageTemplate = messageTemplateSection.children().clone(); this.buttonTemplate = buttonTemplateSection.children().clone(); - messageTemplateSection.remove(); }, /** @@ -579,21 +599,21 @@ TYPO3.Install.coreUpdate = { this.showActionButton(data.action); } if (successMessage) { - this.addMessage('success', successMessage); + this.addMessage(TYPO3.Install.Severity.ok, successMessage); } } else { // Handle clearcache until it uses the new view object if (data === "OK") { canContinue = true; if (successMessage) { - this.addMessage('success', successMessage); + this.addMessage(TYPO3.Install.Severity.ok, successMessage); } } else { canContinue = false; if (data.status && typeof(data.status) === 'object') { this.showStatusMessages(data.status); } else { - this.addMessage('danger', 'General error'); + this.addMessage(TYPO3.Install.Severity.error, 'General error'); } } } @@ -606,10 +626,7 @@ TYPO3.Install.coreUpdate = { * @param messageTitle */ addLoadingMessage: function(messageTitle) { - var domMessage = this.messageTemplate.clone(); - domMessage.find('h4').html(messageTitle); - domMessage.addClass('alert-notice'); - domMessage.find('.messageText').remove(); + var domMessage = TYPO3.Install.FlashMessage.render(TYPO3.Install.Severity.loading, messageTitle); $('#coreUpdate').append(domMessage); }, @@ -617,7 +634,7 @@ TYPO3.Install.coreUpdate = { * Remove an enabled loading message */ removeLoadingMessage: function() { - $('#coreUpdate').find('.alert-notice').closest('.alert').remove(); + $('#coreUpdate').find('.alert-loading').remove(); }, /** @@ -629,11 +646,8 @@ TYPO3.Install.coreUpdate = { var self = this; $.each(messages, function(index, element) { var title = false; - var severity = false; var message = false; - if (element.severity) { - severity = element.severity; - } + var severity = element.severity; if (element.title) { title = element.title; } @@ -676,18 +690,7 @@ TYPO3.Install.coreUpdate = { * @param message */ addMessage: function(severity, title, message) { - var domMessage = this.messageTemplate.clone(); - if (severity) { - domMessage.addClass('alert-' + severity); - } - if (title) { - domMessage.find('h4').html(title); - } - if (message) { - domMessage.find('.messageText').html(message); - } else { - domMessage.find('.messageText').remove(); - } + var domMessage = TYPO3.Install.FlashMessage.render(severity, title, message); $('#coreUpdate').append(domMessage); } }; @@ -719,13 +722,14 @@ $(function() { $panels.collapse(action); }); - if ($('#configSearch').length > 0) { + var $configSearch = $('#configSearch'); + if ($configSearch.length > 0) { $(window).on('keydown', function(event) { if (event.ctrlKey || event.metaKey) { switch (String.fromCharCode(event.which).toLowerCase()) { case 'f': event.preventDefault(); - $('#configSearch').focus(); + $configSearch.focus(); break; } } @@ -775,11 +779,12 @@ $(function() { }).trigger('change'); // Extension compatibility check - $('.t3js-message', '#checkExtensions').hide(); - $('button', '#checkExtensions').click(function(e) { - $('button', '#checkExtensions').hide(); - $('.t3js-message', '#checkExtensions').hide(); - $('.alert-loading', '#checkExtensions').show(); + var $container = $('#checkExtensions'); + $('.t3js-message', $container).hide(); + $('button', $container).click(function(e) { + $('button', $container).hide(); + $('.t3js-message', $container).hide(); + $('.alert-loading', $container).show(); TYPO3.Install.ExtensionChecker.checkExtensionsCompatibility(true); e.preventDefault(); return false; @@ -828,7 +833,7 @@ $(function() { return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); - $('#configSearch').keyup(function() { + $configSearch.keyup(function() { var typedQuery = $(this).val(); $('div.item').each(function() { var $item = $(this); @@ -840,7 +845,7 @@ $(function() { }); $('.searchhit').parent().collapse('show'); }); - var $searchFields = $('#configSearch'); + var $searchFields = $configSearch; var searchResultShown = ('' !== $searchFields.first().val()); // make search field clearable diff --git a/typo3/sysext/install/Tests/Unit/View/JsonViewTest.php b/typo3/sysext/install/Tests/Unit/View/JsonViewTest.php index b179dbaaf506..de554f4eb939 100644 --- a/typo3/sysext/install/Tests/Unit/View/JsonViewTest.php +++ b/typo3/sysext/install/Tests/Unit/View/JsonViewTest.php @@ -48,12 +48,12 @@ class JsonViewTest extends UnitTestCase public function transformStatusToArrayCreatesArrayFromStatusMessage() { $status = $this->createMock(\TYPO3\CMS\Install\Status\StatusInterface::class); - $status->expects($this->once())->method('getSeverity')->will($this->returnValue('aSeverity')); + $status->expects($this->once())->method('getSeverity')->will($this->returnValue(-2)); $status->expects($this->once())->method('getTitle')->will($this->returnValue('aTitle')); $status->expects($this->once())->method('getMessage')->will($this->returnValue('aMessage')); $jsonView = $this->getAccessibleMock(\TYPO3\CMS\Install\View\JsonView::class, ['dummy']); $return = $jsonView->_call('transformStatusToArray', $status); - $this->assertSame('aSeverity', $return['severity']); + $this->assertSame(-2, $return['severity']); $this->assertSame('aTitle', $return['title']); $this->assertSame('aMessage', $return['message']); } -- GitLab