Bug Tracker

Ticket #3076: event-multiple-data.patch

File event-multiple-data.patch, 4.0 KB (added by vmx, 14 years ago)

Test case and bugfix

  • test/unit/event.js

     
    1111        ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
    1212});
    1313
     14test("bind()/unbind(), with same handler but different data", function() {
     15        expect(3);
     16        var data1 = 0, data2 = 0;
     17        var handler = function(event) {
     18                if (event.data.foo)
     19                        data1++;
     20                if (event.data.bar)
     21                        data2++;
     22        };
     23        jQuery("#firstp").bind("click", {foo: "bar"}, handler);//.click().unbind("click", handler);
     24        jQuery("#simon1").bind("click", {foo: "bar"}, handler);//.click().unbind("click", handler);
     25        jQuery("#simon1").bind("click", {foo: "bar"}, handler);//.click().unbind("click", handler);
     26        jQuery("#simon1").bind("click", {bar: "foo"}, handler);//.click().unbind("click", handler);
     27        jQuery("#simon1").bind("click", {bar: "foo"}, handler);//.click().unbind("click", handler);
     28        jQuery("#firstp").bind("click", {bar: "foo"}, handler);//.click().unbind("click", handler);
     29        jQuery("#firstp").bind("click", {foo: "bar"}, handler);//.click().unbind("click", handler);
     30        jQuery("#firstp").bind("click", {bar: "foo"}, handler);//.click().unbind("click", handler);
     31
     32        jQuery("#firstp").click();
     33        jQuery("#simon1").click();
     34        jQuery("#foo").click();
     35
     36        ok( data1==4 && data2==4, "Event handler was bound two times with different data");
     37
     38        jQuery("#firstp").unbind("click", handler);
     39        jQuery("#simon1").unbind("click", handler);
     40        ok( !jQuery.data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different data but same handler. (1)" );
     41        ok( !jQuery.data(jQuery("#simon1")[0], "events"), "Event handler unbound when using different data but same handler. (2)" );
     42});
     43
    1444test("bind(), with data, trigger with data", function() {
    1545        expect(4);
    1646        var handler = function(event, data) {
  • src/event.js

     
    4848                // event in IE.
    4949                handle.elem = elem;
    5050
     51                var guid = this.guid;
     52
    5153                // Handle multiple events separated by a space
    5254                // jQuery(...).bind("mouseover mouseout", fn);
    5355                jQuery.each(types.split(/\s+/), function(index, type) {
     
    7577                                }
    7678                        }
    7779
    78                         // Add the function to the element's handler list
    79                         handlers[handler.guid] = handler;
     80                        // handler with same guid is already bound. If this
     81                        // bind contains data, add the handler again with
     82                        // another guid.
     83                        if (handlers[handler.guid] && data) {
     84                                // add reference to other handlers for
     85                                // unbinding
     86                                if (handlers[handler.guid].prev)
     87                                        // handler has already a reference, put
     88                                        // the new one in between
     89                                        handler.prev = handlers[fn.guid].prev;
     90                                else
     91                                        handler.prev = handler.guid;
    8092
     93                                handler.guid = guid++;
     94                                handlers[handler.guid] = handler;
     95
     96                                // making a cycling reference from one event to
     97                                // eachother to be able to start at any event
     98                                // when unbinding
     99                                handlers[fn.guid].prev = handler.guid;
     100                        }
     101                        else
     102                                handlers[handler.guid] = handler;
     103
    81104                        // Keep track of which events have been used, for global triggering
    82105                        jQuery.event.global[type] = true;
    83106                });
    84107
     108                this.guid = guid;
     109
    85110                // Nullify elem to prevent memory leaks in IE
    86111                elem = null;
    87112        },
     
    118143
    119144                                        if ( events[type] ) {
    120145                                                // remove the given handler for the given type
    121                                                 if ( handler )
     146                                                if ( handler ) {
     147                                                        //same handler was bound several times
     148                                                        //with different data
     149                                                        //var prev = events[type][handler.prev];
     150                                                        var prev = events[type][events[type][handler.guid].prev];
    122151                                                        delete events[type][handler.guid];
    123152
     153                                                        while (prev) {
     154                                                                handler = prev;
     155                                                                prev = events[type][handler.prev];
     156                                                                delete events[type][handler.guid];
     157                                                        }
     158                                                }
    124159                                                // remove all handlers for the given type
    125160                                                else
    126161                                                        for ( handler in events[type] )