This is an automated email from the ASF dual-hosted git repository. papegaaij pushed a commit to branch event-remove-multiple-types in repository https://gitbox.apache.org/repos/asf/wicket.git
commit 967e9f0db42e629107a9c7cb2d56da7417692b8e Author: Emond Papegaaij <[email protected]> AuthorDate: Mon Oct 5 14:25:28 2026 +0200 Let Wicket.Event.remove remove a listener added for several event types Wicket.Event.add in wicket-ajax-jquery.js accepts several space separated event types, as jQuery#on does, but it recorded the listener in its registry under the type string exactly as given, e.g. 'input change'. Wicket.Event.remove splits its type on whitespace and looks the listener up per type, so it found nothing and unbound nothing: remove(el, 'input change', fn), remove(el, 'input', fn) and remove(el, 'input change') all left both events bound. Only remove(el), without any type, still worked. This is a regression from 10.x, where remove delegated to jQuery#off, which handles several types. The jQuery-free wicket-ajax.js was not affected, because its add already records each type separately. add now does the same, so removing a listener works for all of its types at once and for each one on its own. Wicket's own code always adds one type at a time, so only application scripts that add a listener for several types and remove it again see a difference: the listener is now removed. GitHub issue #1646 Co-Authored-By: Claude Opus 5.5 <[email protected]> --- .../wicket/ajax/res/js/wicket-ajax-jquery.js | 12 +++-- wicket-core/src/test/js/event.js | 60 ++++++++++++++++++++++ 2 files changed, 68 insertions(+), 4 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 288dcd004c..605c6604b0 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 @@ -2355,7 +2355,8 @@ * before loading external resources (images, scripts, ...) * * @param element {HTMLElement} The host HTML element - * @param type {String} The type of the DOM event + * @param type {String} The type of the DOM event. Several space separated + * event types can be given at once, e.g. 'input change' * @param fn {Function} The event handler to unbind * @param data {Object} Extra data for the event * @param selector {String} A selector string to filter the descendants of the selected @@ -2394,10 +2395,13 @@ map = {}; Wicket.Event._listenerRegistry.set(el, map); } - if (!map[type]) { - map[type] = []; + const types = type.split(/\s+/); + for (let t = 0; t < types.length; t++) { + if (!map[types[t]]) { + map[types[t]] = []; + } + map[types[t]].push({ fn: fn, wrapper: wrapper }); } - map[type].push({ fn: fn, wrapper: wrapper }); } } return element; diff --git a/wicket-core/src/test/js/event.js b/wicket-core/src/test/js/event.js index e23d5c043d..fa5199f4ad 100644 --- a/wicket-core/src/test/js/event.js +++ b/wicket-core/src/test/js/event.js @@ -183,6 +183,66 @@ Wicket.Event.add(window, 'domready', function() { el.remove(); }); + test('remove - several event types at once', assert => { + + assert.expect(0); + + var el = createTestElement(); + + var handler = function() { + assert.ok(false, 'This event must not be fired!'); + }; + + Wicket.Event.add(el, 'input change', handler); + + Wicket.Event.remove(el, 'input change', handler); + + Wicket.Event.fire(el, 'input'); + Wicket.Event.fire(el, 'change'); + + el.remove(); + }); + + test('remove - one of several event types', assert => { + + assert.expect(1); + + var el = createTestElement(); + + var handler = function(event) { + assert.equal(event.type, 'change', 'Only the event that was not removed must be fired'); + }; + + Wicket.Event.add(el, 'input change', handler); + + Wicket.Event.remove(el, 'input', handler); + + Wicket.Event.fire(el, 'input'); + Wicket.Event.fire(el, 'change'); + + el.remove(); + }); + + test('remove - several event types without a handler', assert => { + + assert.expect(0); + + var el = createTestElement(); + + var handler = function() { + assert.ok(false, 'This event must not be fired!'); + }; + + Wicket.Event.add(el, 'input change', handler); + + Wicket.Event.remove(el, 'input change'); + + Wicket.Event.fire(el, 'input'); + Wicket.Event.fire(el, 'change'); + + el.remove(); + }); + test('add - mousewheel', assert => { assert.expect(1);
