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);

Reply via email to