Use a key name less likely to result in collisions for events on plain JS objects...
[jquery.git] / test / unit / event.js
index b224070..b37b253 100644 (file)
@@ -206,6 +206,45 @@ test("bind/one/unbind(Object)", function(){
        equals( mouseoverCounter, 4, "bind(Object)" );
 });
 
+test("live/die(Object), delegate/undelegate(String, Object)", function() {
+       expect(6);
+       
+       var clickCounter = 0, mouseoverCounter = 0,
+               $p = jQuery("#firstp"), $a = $p.find("a:first");
+       
+       var events = {
+               click: function( event ) {
+                       clickCounter += ( event.data || 1 );
+               },
+               mouseover: function( event ) {
+                       mouseoverCounter += ( event.data || 1 );
+               }
+       };
+       
+       function trigger() {
+               $a.trigger("click").trigger("mouseover");
+       }
+       
+       $a.live( events );
+       $p.delegate( "a", events, 2 );
+       
+       trigger();
+       equals( clickCounter, 3, "live/delegate" );
+       equals( mouseoverCounter, 3, "live/delegate" );
+       
+       $p.undelegate( "a", events );
+       
+       trigger();
+       equals( clickCounter, 4, "undelegate" );
+       equals( mouseoverCounter, 4, "undelegate" );
+       
+       $a.die( events );
+       
+       trigger();
+       equals( clickCounter, 4, "die" );
+       equals( mouseoverCounter, 4, "die" );
+});
+
 test("bind(), iframes", function() {
        // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
        var doc = jQuery("#loadediframe").contents();
@@ -216,7 +255,7 @@ test("bind(), iframes", function() {
 });
 
 test("bind(), trigger change on select", function() {
-       expect(3);
+       expect(5);
        var counter = 0;
        function selectOnChange(event) {
                equals( event.data, counter++, "Event.data is not a global event object" );
@@ -404,7 +443,7 @@ test("bind(name, false), unbind(name, false)", function() {
 });
 
 test("bind()/trigger()/unbind() on plain object", function() {
-       expect( 2 );
+       expect( 5 );
 
        var obj = {};
 
@@ -418,7 +457,11 @@ test("bind()/trigger()/unbind() on plain object", function() {
                ok( true, "Custom event run." );
        });
 
-       ok( jQuery(obj).data("events"), "Object has events bound." );
+       var events = jQuery(obj).data("__events__");
+       ok( events, "Object has events bound." );
+       equals( typeof events, "function", "'events' expando is a function on plain objects." );
+       equals( obj.test, undefined, "Make sure that test event is not on the plain object." );
+       equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
 
        // Should trigger 1
        jQuery(obj).trigger("test");
@@ -443,28 +486,28 @@ test("unbind(type)", function() {
        }
        
        message = "unbind passing function";
-       $elem.bind('error', error).unbind('error',error).triggerHandler('error');
+       $elem.bind('error1', error).unbind('error1',error).triggerHandler('error1');
        
        message = "unbind all from event";
-       $elem.bind('error', error).unbind('error').triggerHandler('error');
+       $elem.bind('error1', error).unbind('error1').triggerHandler('error1');
        
        message = "unbind all";
-       $elem.bind('error', error).unbind().triggerHandler('error');
+       $elem.bind('error1', error).unbind().triggerHandler('error1');
        
        message = "unbind many with function";
-       $elem.bind('error error2',error)
-                .unbind('error error2', error )
-                .trigger('error').triggerHandler('error2');
+       $elem.bind('error1 error2',error)
+                .unbind('error1 error2', error )
+                .trigger('error1').triggerHandler('error2');
 
        message = "unbind many"; // #3538
-       $elem.bind('error error2',error)
-                .unbind('error error2')
-                .trigger('error').triggerHandler('error2');
+       $elem.bind('error1 error2',error)
+                .unbind('error1 error2')
+                .trigger('error1').triggerHandler('error2');
        
        message = "unbind without a type or handler";
-       $elem.bind("error error2.test",error)
+       $elem.bind("error1 error2.test",error)
                 .unbind()
-                .trigger("error").triggerHandler("error2");
+                .trigger("error1").triggerHandler("error2");
 });
 
 test("unbind(eventObject)", function() {
@@ -978,17 +1021,20 @@ test(".live()/.die()", function() {
        jQuery("#nothiddendiv").trigger("click");
        equals( called, 1, "Verify that only one click occurred." );
 
+       called = 0;
        jQuery("#anchor2").trigger("click");
-       equals( called, 2, "Verify that only one click occurred." );
+       equals( called, 1, "Verify that only one click occurred." );
 
        // Make sure that only one callback is removed
        jQuery("#anchor2").die("click", callback);
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("click");
-       equals( called, 3, "Verify that only one click occurred." );
+       equals( called, 1, "Verify that only one click occurred." );
 
+       called = 0;
        jQuery("#anchor2").trigger("click");
-       equals( called, 3, "Verify that no click occurred." );
+       equals( called, 0, "Verify that no click occurred." );
 
        // Make sure that it still works if the selector is the same,
        // but the event type is different
@@ -997,11 +1043,13 @@ test(".live()/.die()", function() {
        // Cleanup
        jQuery("#nothiddendiv").die("click", callback);
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("click");
-       equals( called, 3, "Verify that no click occurred." );
+       equals( called, 0, "Verify that no click occurred." );
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("foo");
-       equals( called, 4, "Verify that one foo occurred." );
+       equals( called, 1, "Verify that one foo occurred." );
 
        // Cleanup
        jQuery("#nothiddendiv").die("foo", callback);
@@ -1135,41 +1183,55 @@ test("live with multiple events", function(){
 });
 
 test("live with namespaces", function(){
-       expect(6);
+       expect(12);
 
        var count1 = 0, count2 = 0;
 
-       jQuery("#liveSpan1").live("foo.bar", function(){
+       jQuery("#liveSpan1").live("foo.bar", function(e){
                count1++;
        });
 
-       jQuery("#liveSpan2").live("foo.zed", function(){
+       jQuery("#liveSpan1").live("foo.zed", function(e){
                count2++;
        });
 
        jQuery("#liveSpan1").trigger("foo.bar");
        equals( count1, 1, "Got live foo.bar" );
+       equals( count2, 0, "Got live foo.bar" );
+
+       count1 = 0, count2 = 0;
 
-       jQuery("#liveSpan2").trigger("foo.zed");
+       jQuery("#liveSpan1").trigger("foo.zed");
+       equals( count1, 0, "Got live foo.zed" );
        equals( count2, 1, "Got live foo.zed" );
 
        //remove one
-       jQuery("#liveSpan2").die("foo.zed");
+       count1 = 0, count2 = 0;
+
+       jQuery("#liveSpan1").die("foo.zed");
        jQuery("#liveSpan1").trigger("foo.bar");
 
-       equals( count1, 2, "Got live foo.bar after dieing foo.zed" );
+       equals( count1, 1, "Got live foo.bar after dieing foo.zed" );
+       equals( count2, 0, "Got live foo.bar after dieing foo.zed" );
 
-       jQuery("#liveSpan2").trigger("foo.zed");
-       equals( count2, 1, "Got live foo.zed" );
+       count1 = 0, count2 = 0;
+
+       jQuery("#liveSpan1").trigger("foo.zed");
+       equals( count1, 0, "Got live foo.zed" );
+       equals( count2, 0, "Got live foo.zed" );
 
        //remove the other
        jQuery("#liveSpan1").die("foo.bar");
 
+       count1 = 0, count2 = 0;
+
        jQuery("#liveSpan1").trigger("foo.bar");
-       equals( count1, 2, "Did not respond to foo.bar after dieing it" );
+       equals( count1, 0, "Did not respond to foo.bar after dieing it" );
+       equals( count2, 0, "Did not respond to foo.bar after dieing it" );
 
-       jQuery("#liveSpan2").trigger("foo.zed");
-       equals( count2, 1, "Did not trigger foo.zed again" );
+       jQuery("#liveSpan1").trigger("foo.zed");
+       equals( count1, 0, "Did not trigger foo.zed again" );
+       equals( count2, 0, "Did not trigger foo.zed again" );
 });
 
 test("live with change", function(){
@@ -1278,21 +1340,64 @@ test("live with submit", function() {
                ev.preventDefault();
        });
 
-       if ( jQuery.support.submitBubbles ) {
-               jQuery("#testForm input[name=sub1]")[0].click();
-               equals(count1,1 );
-               equals(count2,1);
-       } else {
-               jQuery("#testForm input[name=sub1]")[0].click();
-               jQuery("#testForm input[name=T1]").trigger({type: "keypress", keyCode: 13});
-               equals(count1,2);
-               equals(count2,2);
-       }
+       jQuery("#testForm input[name=sub1]").submit();
+       equals( count1, 1, "Verify form submit." );
+       equals( count2, 1, "Verify body submit." );
        
        jQuery("#testForm").die("submit");
        jQuery("body").die("submit");
 });
 
+test("live with special events", function() {
+       expect(13);
+
+       jQuery.event.special.foo = {
+               setup: function( data, namespaces, handler ) {
+                       ok( true, "Setup run." );
+               },
+               teardown: function( namespaces ) {
+                       ok( true, "Teardown run." );
+               },
+               add: function( handleObj ) {
+                       ok( true, "Add run." );
+               },
+               remove: function( handleObj ) {
+                       ok( true, "Remove run." );
+               },
+               _default: function( event ) {
+                       ok( true, "Default run." );
+               }
+       };
+
+       // Run: setup, add
+       jQuery("#liveSpan1").live("foo.a", function(e){
+               ok( true, "Handler 1 run." );
+       });
+
+       // Run: add
+       jQuery("#liveSpan1").live("foo.b", function(e){
+               ok( true, "Handler 2 run." );
+       });
+
+       // Run: Handler 1, Handler 2, Default
+       jQuery("#liveSpan1").trigger("foo");
+
+       // Run: Handler 1, Default
+       // TODO: Namespace doesn't trigger default (?)
+       jQuery("#liveSpan1").trigger("foo.a");
+
+       // Run: remove
+       jQuery("#liveSpan1").die("foo.a");
+
+       // Run: Handler 2, Default
+       jQuery("#liveSpan1").trigger("foo");
+
+       // Run: remove, teardown
+       jQuery("#liveSpan1").die("foo");
+
+       delete jQuery.event.special.foo;
+});
+
 test(".delegate()/.undelegate()", function() {
        expect(65);
 
@@ -1446,17 +1551,20 @@ test(".delegate()/.undelegate()", function() {
        jQuery("#nothiddendiv").trigger("click");
        equals( called, 1, "Verify that only one click occurred." );
 
+       called = 0;
        jQuery("#anchor2").trigger("click");
-       equals( called, 2, "Verify that only one click occurred." );
+       equals( called, 1, "Verify that only one click occurred." );
 
        // Make sure that only one callback is removed
        jQuery("#body").undelegate("#anchor2", "click", callback);
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("click");
-       equals( called, 3, "Verify that only one click occurred." );
+       equals( called, 1, "Verify that only one click occurred." );
 
+       called = 0;
        jQuery("#anchor2").trigger("click");
-       equals( called, 3, "Verify that no click occurred." );
+       equals( called, 0, "Verify that no click occurred." );
 
        // Make sure that it still works if the selector is the same,
        // but the event type is different
@@ -1465,11 +1573,13 @@ test(".delegate()/.undelegate()", function() {
        // Cleanup
        jQuery("#body").undelegate("#nothiddendiv", "click", callback);
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("click");
-       equals( called, 3, "Verify that no click occurred." );
+       equals( called, 0, "Verify that no click occurred." );
 
+       called = 0;
        jQuery("#nothiddendiv").trigger("foo");
-       equals( called, 4, "Verify that one foo occurred." );
+       equals( called, 1, "Verify that one foo occurred." );
 
        // Cleanup
        jQuery("#body").undelegate("#nothiddendiv", "foo", callback);
@@ -1699,16 +1809,9 @@ test("delegate with submit", function() {
                ev.preventDefault();
        });
 
-       if ( jQuery.support.submitBubbles ) {
-               jQuery("#testForm input[name=sub1]")[0].click();
-               equals(count1,1 );
-               equals(count2,1);
-       } else {
-               jQuery("#testForm input[name=sub1]")[0].click();
-               jQuery("#testForm input[name=T1]").trigger({type: "keypress", keyCode: 13});
-               equals(count1,2);
-               equals(count2,2);
-       }
+       jQuery("#testForm input[name=sub1]").submit();
+       equals( count1, 1, "Verify form submit." );
+       equals( count2, 1, "Verify body submit." );
        
        jQuery("#body").undelegate();
        jQuery(document).undelegate();
@@ -1726,6 +1829,18 @@ test("Non DOM element events", function() {
        jQuery(o).trigger('nonelementobj');
 });
 
+test("window resize", function() {
+       expect(2);
+
+       jQuery(window).unbind();
+
+       jQuery(window).bind("resize", function(){
+               ok( true, "Resize event fired." );
+       }).resize().unbind("resize");
+
+       ok( !jQuery(window).data("events"), "Make sure all the events are gone." );
+});
+
 /*
 test("jQuery(function($) {})", function() {
        stop();