js: Don't trigger beforerender or rendered for discarded content

A listener for `rendered` should not need to check if the content
really changed. Though, if such a listener is not triggered anymore,
`beforerender` listeners also must not be triggered, as they might
assume that the content is really being updated and their accompanied
`rendered` listener is triggered. (e.g. input-enrichment.js)

This might be breaking change and any `Behavior.renderHook` implementation
needs to be checked against it. Potentially also in third party modules.
As if such an implementation updates the container on its own,
`beforerender` listeners only have access to the updated container after
this change, while they had access to the original beforehand.

`rendered` listeners should not be that much affected, as for them the
change results in the same behavior as if no update has ever been
scheduled for the container.

fixes #5056
This commit is contained in:
Johannes Meyer 2023-07-07 11:22:39 +02:00
parent d311005089
commit ef4bd5653c

View File

@ -873,7 +873,7 @@
} }
}) })
} else { } else {
this.renderContentToContainer( let rendered = this.renderContentToContainer(
req.responseText, req.responseText,
req.$target, req.$target,
req.action, req.action,
@ -882,6 +882,10 @@
req.autosubmit || autoSubmit, req.autosubmit || autoSubmit,
req.scripted req.scripted
); );
if (! rendered) {
req.discarded = true;
}
} }
if (oldNotifications) { if (oldNotifications) {
@ -905,6 +909,14 @@
req = reqOrError; req = reqOrError;
} }
req.$target.data('lastUpdate', (new Date()).getTime());
delete this.requests[req.$target.attr('id')];
this.icinga.ui.fadeNotificationsAway();
if (req.discarded) {
return;
}
// Remove 'impact' class if there was such // Remove 'impact' class if there was such
if (req.$target.hasClass('impact')) { if (req.$target.hasClass('impact')) {
req.$target.removeClass('impact'); req.$target.removeClass('impact');
@ -957,10 +969,6 @@
} }
} }
req.$target.data('lastUpdate', (new Date()).getTime());
delete this.requests[req.$target.attr('id')];
this.icinga.ui.fadeNotificationsAway();
var extraUpdates = req.getResponseHeader('X-Icinga-Extra-Updates'); var extraUpdates = req.getResponseHeader('X-Icinga-Extra-Updates');
if (!! extraUpdates && req.getResponseHeader('X-Icinga-Redirect-Http') !== 'yes') { if (!! extraUpdates && req.getResponseHeader('X-Icinga-Redirect-Http') !== 'yes') {
$.each(extraUpdates.split(','), function (idx, el) { $.each(extraUpdates.split(','), function (idx, el) {
@ -1253,8 +1261,6 @@
} }
} }
$container.trigger('beforerender', [content, action, autorefresh, scripted, autoSubmit]);
var discard = false; var discard = false;
$.each(_this.icinga.behaviors, function(name, behavior) { $.each(_this.icinga.behaviors, function(name, behavior) {
if (behavior.renderHook) { if (behavior.renderHook) {
@ -1272,6 +1278,8 @@
}); });
if (! discard) { if (! discard) {
$container.trigger('beforerender', [content, action, autorefresh, scripted, autoSubmit]);
if ($container.closest('.dashboard').length) { if ($container.closest('.dashboard').length) {
var title = $('h1', $container).first().detach(); var title = $('h1', $container).first().detach();
$container.html(title).append(content); $container.html(title).append(content);
@ -1337,6 +1345,8 @@
// Re-enable all click events (disabled as of performance reasons) // Re-enable all click events (disabled as of performance reasons)
// $('*').off('click'); // $('*').off('click');
return ! discard;
}, },
/** /**