This is an automated email from the ASF dual-hosted git repository. reiern70 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/wicket.git
commit b9a8243e304ba99bd75593f0a79993590fa3874b Author: reiern70 <[email protected]> AuthorDate: Fri Oct 2 10:49:36 2026 -0500 Lower the Ajax veil on a redirect again, and leave core unchanged The previous commit kept the veil up when the response redirected the browser, and made both Ajax engines pass whether the call is redirecting to /ajax/call/done for that. But a redirect does not always leave the page: a redirect to a download, a mailto: link or a URL answering 204, or a navigation the user cancels at a beforeunload prompt, all keep the page, and the browser fires no event to tell. The veil then never came down, and with a PageVeilBehavior on a base page the whole page stayed blocked until it was reloaded. No timeout can tell these cases from a slow page load. The slow part the veil is there for, the server's work, is covered either way, and the window between the response and the next page is the one every Wicket application already has. The veil comes down at /ajax/call/done for a redirect too, as before, and the change to the Ajax engines, its tests and its documentation are reverted, so the veil needs nothing from core. See GitHub issue #1631. --- .../wicket/ajax/res/js/wicket-ajax-jquery.js | 6 ++-- .../org/apache/wicket/ajax/res/js/wicket-ajax.js | 6 ++-- wicket-core/src/test/js/ajax.js | 40 ---------------------- .../extensions/ajax/veil/AbstractVeilBehavior.java | 5 --- .../wicket/extensions/ajax/veil/wicket-veil.js | 15 ++------ wicket-extensions/src/test/js/veil-test.js | 22 ++---------- .../src/main/asciidoc/ajax/ajax_12.adoc | 2 -- .../src/main/asciidoc/ajax/ajax_6.adoc | 2 +- 8 files changed, 12 insertions(+), 86 deletions(-) diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js index 11540e767e..288dcd004c 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js @@ -742,7 +742,7 @@ self._executeHandlers(attrs.coh, attrs, jqXHR, textStatus); we.publish(topic.AJAX_CALL_COMPLETE, attrs, jqXHR, textStatus); - self.done(attrs, context.isRedirecting === true); + self.done(attrs); return FunctionsExecuter.DONE; }, self)); @@ -929,9 +929,9 @@ }, this)); }, - done: function (attrs, isRedirecting) { + done: function (attrs) { this._executeHandlers(attrs.dh, attrs); - Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs, isRedirecting === true); + Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs); Wicket.channelManager.done(attrs.ch); }, diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax.js b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax.js index d24e0a5f20..befb85810a 100644 --- a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax.js +++ b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax.js @@ -956,7 +956,7 @@ self._executeHandlers(attrs.coh, attrs, xhr, textStatus); we.publish(topic.AJAX_CALL_COMPLETE, attrs, xhr, textStatus); - self.done(attrs, context.isRedirecting === true); + self.done(attrs); return FunctionsExecuter.DONE; }).bind(self)); @@ -1143,9 +1143,9 @@ }).bind(this)); }, - done: function (attrs, isRedirecting) { + done: function (attrs) { this._executeHandlers(attrs.dh, attrs); - Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs, isRedirecting === true); + Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs); Wicket.channelManager.done(attrs.ch); }, diff --git a/wicket-core/src/test/js/ajax.js b/wicket-core/src/test/js/ajax.js index 1937e3bbc4..8a173f6358 100644 --- a/wicket-core/src/test/js/ajax.js +++ b/wicket-core/src/test/js/ajax.js @@ -1327,46 +1327,6 @@ Wicket.Event.add(window, 'domready', function() { Wicket.Event.remove(window, "event1"); }); - test('The done topic tells its subscribers that the response redirects.', assert => { - const done = assert.async(); - assert.expect(1); - - var oldRedirect = Wicket.Ajax.redirect; - Wicket.Ajax.redirect = function() {}; - - Wicket.Event.subscribe('/ajax/call/done', function(jqEvent, attributes, isRedirecting) { - assert.strictEqual(isRedirecting, true, 'Done: isRedirecting'); - Wicket.Event.unsubscribe(); - Wicket.Ajax.redirect = oldRedirect; - done(); - }); - - Wicket.Ajax.ajax({ - u: 'data/ajax/redirectAjaxResponse.xml', - e: 'event1' - }); - Wicket.Event.fire(window, "event1"); - Wicket.Event.remove(window, "event1"); - }); - - test('The done topic tells its subscribers that the response does not redirect.', assert => { - const done = assert.async(); - assert.expect(1); - - Wicket.Event.subscribe('/ajax/call/done', function(jqEvent, attributes, isRedirecting) { - assert.strictEqual(isRedirecting, false, 'Done: isRedirecting'); - Wicket.Event.unsubscribe(); - done(); - }); - - Wicket.Ajax.ajax({ - u: 'data/ajax/emptyAjaxResponse.xml', - e: 'event1' - }); - Wicket.Event.fire(window, "event1"); - Wicket.Event.remove(window, "event1"); - }); - test('processAjaxResponse, normal HTTP case.', assert => { const done = assert.async(); assert.expect(2); diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/AbstractVeilBehavior.java b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/AbstractVeilBehavior.java index 5f197d0e23..8f77ebdb29 100644 --- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/AbstractVeilBehavior.java +++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/AbstractVeilBehavior.java @@ -44,11 +44,6 @@ import org.apache.wicket.util.lang.Args; * alike, and can be changed per behavior with {@link #setSpinnerDelay(Duration)} and * {@link #setMinimumSpinnerTime(Duration)}. The veil does not intercept the keyboard. * <p> - * When the response redirects the browser to another page, the veil stays up until the browser - * leaves the page, so the request cannot be sent again meanwhile. A redirect that does not leave - * the page, such as one to a file download, leaves the veil up too; offer downloads through - * {@link org.apache.wicket.extensions.ajax.AjaxDownloadBehavior} instead. - * <p> * The look comes from {@code wicket-veil.css} and can be overridden with the classes * {@code wicket-veil}, {@code wicket-veil-busy}, {@code wicket-veil-host} and * {@code wicket-veil-host-static}. diff --git a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/wicket-veil.js b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/wicket-veil.js index 718c433dbb..ce14e34060 100644 --- a/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/wicket-veil.js +++ b/wicket-extensions/src/main/java/org/apache/wicket/extensions/ajax/veil/wicket-veil.js @@ -21,8 +21,7 @@ * The veil is transparent and only blocks the mouse. If a request is still running after the * target's spinner delay, the veil gets the 'wicket-veil-busy' class, which shows a spinner; * once shown, the spinner stays for at least the target's minimum time, so it does not flicker. - * A request carrying the extra parameter 'wicket_nb' is never veiled. A request whose response - * redirects the browser keeps its veil until the page is left. + * A request carrying the extra parameter 'wicket_nb' is never veiled. * * A local veil can also be raised by the server, for a component it is about to update through a * WebSocket push: a WebSocket text message {"wicketVeil":"show","id":"<markup id>"} raises it, @@ -247,9 +246,9 @@ acquire(target); } - function onDone(jqEvent, attrs, isRedirecting) { + function onDone(jqEvent, attrs) { const target = attrs && attrs.wicketVeil; - if (!target || isRedirecting === true) { + if (!target) { return; } delete attrs.wicketVeil; @@ -262,13 +261,6 @@ } } - function onPageShow(event) { - // a page restored from the back-forward cache may still carry the veil of a redirect - if (event.persisted) { - lowerAll(); - } - } - function onWebSocketMessage(jqEvent, message) { if (typeof(message) !== "string" || message.indexOf(MESSAGE_PREFIX) !== 0) { return; @@ -293,7 +285,6 @@ Wicket.Event.subscribe(Wicket.Event.Topic.AJAX_CALL_DONE, onDone); Wicket.Event.subscribe(Wicket.Event.Topic.DOM_NODE_ADDED, onDomNodeAdded); Wicket.Event.subscribe(WEBSOCKET_MESSAGE_TOPIC, onWebSocketMessage); - window.addEventListener('pageshow', onPageShow); } } diff --git a/wicket-extensions/src/test/js/veil-test.js b/wicket-extensions/src/test/js/veil-test.js index 7b9cc6a5fd..7420b03ad9 100644 --- a/wicket-extensions/src/test/js/veil-test.js +++ b/wicket-extensions/src/test/js/veil-test.js @@ -71,8 +71,8 @@ Wicket.Event.add(window, 'domready', function() { return attrs; } - function done(attrs, isRedirecting) { - Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs, isRedirecting === true); + function done(attrs) { + Wicket.Event.publish(Wicket.Event.Topic.AJAX_CALL_DONE, attrs); } function push(message) { @@ -504,24 +504,6 @@ Wicket.Event.add(window, 'domready', function() { assert.equal(veils().length, 0, "the veil stayed after it was hidden"); }); - test("a response redirecting the browser keeps the veil until the page is left", assert => { - Wicket.Veil.page(OPTIONS); - - const attrs = send({ c: 'veilPageLink' }); - done(attrs, true); - clock.tick(1000); - assert.ok(veilOf(document.body), "the veil came down although the browser is leaving the page"); - assert.ok(isBusy(veilOf(document.body)), "the spinner did not show while the browser is leaving the page"); - - window.dispatchEvent(new window.PageTransitionEvent('pageshow', { persisted: true })); - assert.equal(veils().length, 0, "the veil stayed on the page restored from the back-forward cache"); - - const next = send({ c: 'veilPageLink' }); - assert.ok(veilOf(document.body), "the next request was not veiled"); - done(next); - assert.equal(veils().length, 0, "the veil stayed after the next request finished"); - }); - test("an unmatched hide leaves the veil of a running request alone", assert => { Wicket.Veil.local('veilOuter', OPTIONS); const outer = document.getElementById('veilOuter'); diff --git a/wicket-user-guide/src/main/asciidoc/ajax/ajax_12.adoc b/wicket-user-guide/src/main/asciidoc/ajax/ajax_12.adoc index baec6c6e92..23bb4a5bf0 100644 --- a/wicket-user-guide/src/main/asciidoc/ajax/ajax_12.adoc +++ b/wicket-user-guide/src/main/asciidoc/ajax/ajax_12.adoc @@ -18,8 +18,6 @@ public class BasePage extends WebPage { Adding it to any other component throws an _IllegalArgumentException_. -When the response redirects the browser to another page, for example after _setResponsePage()_, the veil stays up until the browser leaves the page, so a second click cannot send the request again in the meantime. A redirect that does not leave the page, such as one to a file download, leaves the veil up as well; offer downloads through _AjaxDownloadBehavior_ instead. - === Veiling a single component _LocalVeilBehavior_ veils only the component it is added to, and only during the AJAX requests fired by that component or by a component nested in it. The rest of the page stays usable: diff --git a/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc b/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc index e7d964fb18..a940d01aeb 100644 --- a/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc +++ b/wicket-user-guide/src/main/asciidoc/ajax/ajax_6.adoc @@ -153,7 +153,7 @@ Global AJAX call events are handled with JavaScript. We can register a callback * '/ajax/call/success': called if the AJAX call has successfully returned. * '/ajax/call/failure': called if the AJAX call has returned with a failure. * '/ajax/call/complete': called when the AJAX call has completed. -* '/ajax/call/done': called when the AJAX call is done. Its callback gets, after attrs, a boolean telling whether the response is redirecting the browser to another page, in which case the page is about to be left and anything blocking it can stay up. +* '/ajax/call/done': called when the AJAX call is done. * '/dom/node/removing': called when a component is about to be removed via AJAX. This happens when component markup is updated via AJAX (i.e. the component itself or one of its containers has been added to _AjaxRequestTarget_) * '/dom/node/added': called when a component has been added via AJAX. Just like '/dom/node/removing', this event is triggered when a component is added to _AjaxRequestTarget_.
