diff options
Diffstat (limited to 'test/unit/event.js')
-rw-r--r-- | test/unit/event.js | 341 |
1 files changed, 302 insertions, 39 deletions
diff --git a/test/unit/event.js b/test/unit/event.js index a1aee191f..c00eb202c 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -14,6 +14,51 @@ test("null or undefined handler", function() { } catch (e) {} }); +test("bind(),live(),delegate() with non-null,defined data", function() { + + expect(3); + + var handler = function( event, data ) { + equal( data, 0, "non-null, defined data (zero) is correctly passed" ); + }; + + jQuery("#foo").bind("foo", handler); + jQuery("#foo").live("foo", handler); + jQuery("div").delegate("#foo", "foo", handler); + + jQuery("#foo").trigger("foo", 0); + + jQuery("#foo").unbind("foo", handler); + jQuery("#foo").die("foo", handler); + jQuery("div").undelegate("#foo", "foo"); + +}); + +/* +Removed because Chrome 13 snaps/crashes on this 2011-09-07 + +test("Handler changes and .trigger() order", function() { + expect(1); + + var markup = jQuery( + '<div><p><b class="a">b</b></p></div>' + ).appendTo( "body" ); + + var path = ""; + jQuery( "b" ).parents().bind( "click", function(e){ + path += this.nodeName.toLowerCase() + " "; + // Should not change the event triggering order + $(this).parent().remove(); + }); + + markup.find( "b" ).trigger( "click" ); + + equals( path, "p div body html ", "Delivered all events" ) + + markup.remove(); +}); +*/ + test("bind(), with data", function() { expect(4); var handler = function(event) { @@ -68,6 +113,22 @@ test("bind(), multiple events at once", function() { equals( mouseoverCounter, 1, "bind() with multiple events at once" ); }); +test("bind(), five events at once", function() { + expect(1); + + var count = 0, + handler = function(event) { + count++; + }; + + jQuery("#firstp").bind("click mouseover foo bar baz", handler) + .trigger("click").trigger("mouseover") + .trigger("foo").trigger("bar") + .trigger("baz"); + + equals( count, 5, "bind() five events at once" ); +}); + test("bind(), multiple events at once and namespaces", function() { expect(7); @@ -112,7 +173,7 @@ test("bind(), multiple events at once and namespaces", function() { }); test("bind(), namespace with special add", function() { - expect(24); + expect(27); var div = jQuery("<div/>").bind("test", function(e) { ok( true, "Test event fired." ); @@ -121,10 +182,11 @@ test("bind(), namespace with special add", function() { var i = 0; jQuery.event.special.test = { - _default: function(e) { + _default: function(e, data) { equals( this, document, "Make sure we're at the top of the chain." ); equals( e.type, "test", "And that we're still dealing with a test event." ); equals( e.target, div[0], "And that the target is correct." ); + ok( data !== undefined , "And that trigger data was passed." ); }, setup: function(){}, teardown: function(){ @@ -153,13 +215,13 @@ test("bind(), namespace with special add", function() { }); // Should trigger 5 - div.trigger("test"); + div.trigger("test", 33.33); // Should trigger 2 - div.trigger("test.a"); + div.trigger("test.a", "George Harrison"); // Should trigger 2 - div.trigger("test.b"); + div.trigger("test.b", { year: 1982 }); // Should trigger 4 div.unbind("test"); @@ -169,7 +231,7 @@ test("bind(), namespace with special add", function() { }); // Should trigger 2 - div.appendTo("#main").remove(); + div.appendTo("#qunit-fixture").remove(); delete jQuery.event.special.test; }); @@ -307,7 +369,7 @@ test("live/delegate immediate propagation", function() { test("bind/delegate bubbling, isDefaultPrevented", function() { expect(2); var $anchor2 = jQuery( "#anchor2" ), - $main = jQuery( "#main" ), + $main = jQuery( "#qunit-fixture" ), fakeClick = function($jq) { // Use a native click so we don't get jQuery simulated bubbling if ( document.createEvent ) { @@ -415,7 +477,7 @@ test("bind(), namespaced events, cloned events", 18, function() { }).trigger("tester"); // Make sure events stick with appendTo'd elements (which are cloned) #2027 - jQuery("<a href='#fail' class='test'>test</a>").click(function(){ return false; }).appendTo("#main"); + jQuery("<a href='#fail' class='test'>test</a>").click(function(){ return false; }).appendTo("#qunit-fixture"); ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" ); }); @@ -538,7 +600,7 @@ test("bind(name, false), unbind(name, false)", function() { expect(3); var main = 0; - jQuery("#main").bind("click", function(e){ main++; }); + jQuery("#qunit-fixture").bind("click", function(e){ main++; }); jQuery("#ap").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); @@ -553,14 +615,14 @@ test("bind(name, false), unbind(name, false)", function() { equals( main, 1, "Verify that the trigger happened correctly." ); // manually clean up events from elements outside the fixture - jQuery("#main").unbind("click"); + jQuery("#qunit-fixture").unbind("click"); }); test("live(name, false), die(name, false)", function() { expect(3); var main = 0; - jQuery("#main").live("click", function(e){ main++; }); + jQuery("#qunit-fixture").live("click", function(e){ main++; }); jQuery("#ap").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); @@ -573,7 +635,7 @@ test("live(name, false), die(name, false)", function() { jQuery("#ap").die("click", false); jQuery("#ap").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); - jQuery("#main").die("click"); + jQuery("#qunit-fixture").die("click"); }); test("delegate(selector, name, false), undelegate(selector, name, false)", function() { @@ -581,7 +643,7 @@ test("delegate(selector, name, false), undelegate(selector, name, false)", funct var main = 0; - jQuery("#main").delegate("#ap", "click", function(e){ main++; }); + jQuery("#qunit-fixture").delegate("#ap", "click", function(e){ main++; }); jQuery("#ap").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); @@ -594,7 +656,7 @@ test("delegate(selector, name, false), undelegate(selector, name, false)", funct jQuery("#ap").undelegate("#groups", "click", false); jQuery("#groups").trigger("click"); equals( main, 1, "Verify that the trigger happened correctly." ); - jQuery("#main").undelegate("#ap", "click"); + jQuery("#qunit-fixture").undelegate("#ap", "click"); }); test("bind()/trigger()/unbind() on plain object", function() { @@ -744,6 +806,43 @@ test("mouseover triggers mouseenter", function() { elem.remove(); }); +test("withinElement implemented with jQuery.contains()", function() { + + expect(1); + + jQuery("#qunit-fixture").append('<div id="jc-outer"><div id="jc-inner"></div></div>'); + + jQuery("#jc-outer").bind("mouseenter mouseleave", function( event ) { + + equal( this.id, "jc-outer", this.id + " " + event.type ); + + }).trigger("mouseenter"); + + jQuery("#jc-inner").trigger("mousenter"); + + jQuery("#jc-outer").unbind("mouseenter mouseleave").remove(); + jQuery("#jc-inner").remove(); + +}); + +test("mouseenter, mouseleave don't catch exceptions", function() { + expect(2); + + var elem = jQuery("#firstp").hover(function() { throw "an Exception"; }); + + try { + elem.mouseenter(); + } catch (e) { + equals( e, "an Exception", "mouseenter doesn't catch exceptions" ); + } + + try { + elem.mouseleave(); + } catch (e) { + equals( e, "an Exception", "mouseleave doesn't catch exceptions" ); + } +}); + test("trigger() shortcuts", function() { expect(6); @@ -798,7 +897,7 @@ test("trigger() bubbling", function() { jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } }); jQuery("html").bind("click", function(e){ html++; }); jQuery("body").bind("click", function(e){ body++; }); - jQuery("#main").bind("click", function(e){ main++; }); + jQuery("#qunit-fixture").bind("click", function(e){ main++; }); jQuery("#ap").bind("click", function(){ ap++; return false; }); jQuery("html").trigger("click"); @@ -812,7 +911,7 @@ test("trigger() bubbling", function() { equals( html, 2, "Body bubble" ); equals( body, 1, "Body bubble" ); - jQuery("#main").trigger("click"); + jQuery("#qunit-fixture").trigger("click"); equals( win, 3, "Main bubble" ); equals( doc, 3, "Main bubble" ); equals( html, 3, "Main bubble" ); @@ -828,11 +927,11 @@ test("trigger() bubbling", function() { // manually clean up events from elements outside the fixture jQuery(document).unbind("click"); - jQuery("html, body, #main").unbind("click"); + jQuery("html, body, #qunit-fixture").unbind("click"); }); test("trigger(type, [data], [fn])", function() { - expect(14); + expect(16); var handler = function(event, a, b, c) { equals( event.type, "click", "check passed data" ); @@ -849,7 +948,24 @@ test("trigger(type, [data], [fn])", function() { ok( true, "Native call was triggered" ); }; - // Triggers handlrs and native + + $elem.live('mouseenter', function(){ + ok( true, 'Trigger mouseenter bound by live' ); + }); + + $elem.live('mouseleave', function(){ + ok( true, 'Trigger mouseleave bound by live' ); + }); + + $elem.trigger('mouseenter'); + + $elem.trigger('mouseleave'); + + $elem.die('mouseenter'); + + $elem.die('mouseleave'); + + // Triggers handlrs and native // Trigger 5 $elem.bind("click", handler).trigger("click", [1, "2", "abc"]); @@ -872,7 +988,7 @@ test("trigger(type, [data], [fn])", function() { pass = true; try { - jQuery("#main table:first").bind("test:test", function(){}).trigger("test:test"); + jQuery("#qunit-fixture table:first").bind("test:test", function(){}).trigger("test:test"); } catch (e) { pass = false; } @@ -904,9 +1020,6 @@ test("trigger(type, [data], [fn])", function() { form.remove(); }); -test("jQuery.Event.currentTarget", function(){ -}); - test("trigger(eventObject, [data], [fn])", function() { expect(25); @@ -1101,7 +1214,7 @@ test("toggle(Function, Function, ...)", function() { }); test(".live()/.die()", function() { - expect(66); + expect(65); var submit = 0, div = 0, livea = 0, liveb = 0; @@ -1189,17 +1302,14 @@ test(".live()/.die()", function() { jQuery("div").die("submit"); // Test binding with a different context - var clicked = 0, container = jQuery("#main")[0]; + var clicked = 0, container = jQuery("#qunit-fixture")[0]; jQuery("#foo", container).live("click", function(e){ clicked++; }); jQuery("div").trigger("click"); jQuery("#foo").trigger("click"); - jQuery("#main").trigger("click"); + jQuery("#qunit-fixture").trigger("click"); jQuery("body").trigger("click"); equals( clicked, 2, "live with a context" ); - // Make sure the event is actually stored on the context - ok( jQuery._data(container, "events").live, "live with a context" ); - // Test unbinding with a different context jQuery("#foo", container).die("click"); jQuery("#foo").trigger("click"); @@ -1372,6 +1482,9 @@ test(".live()/.die()", function() { jQuery("#nothiddendiv div").die("click"); + // div must have a tabindex to be focusable + jQuery("#nothiddendiv div").attr("tabindex", "0")[0].focus(); + jQuery("#nothiddendiv div").live("blur", function(){ ok( true, "Live div trigger blur." ); }); @@ -1546,7 +1659,7 @@ test("live with change", function(){ }); test("live with submit", function() { - expect(5); + expect(7); var count1 = 0, count2 = 0; @@ -1572,6 +1685,10 @@ test("live with submit", function() { equals( count1, 2, "Verify form submit." ); equals( count2, 2, "Verify body submit." ); + jQuery("#testForm button[name=sub4]")[0].click(); + equals( count1, 3, "Verify form submit." ); + equals( count2, 3, "Verify body submit." ); + jQuery("#testForm").die("submit"); jQuery("#testForm input[name=sub1]").die("click"); jQuery("body").die("submit"); @@ -1612,7 +1729,6 @@ test("live with special events", function() { jQuery("#liveSpan1").trigger("foo"); // Run: Handler 1, Default - // TODO: Namespace doesn't trigger default (?) jQuery("#liveSpan1").trigger("foo.a"); // Run: remove @@ -1628,7 +1744,7 @@ test("live with special events", function() { }); test(".delegate()/.undelegate()", function() { - expect(65); + expect(64); var submit = 0, div = 0, livea = 0, liveb = 0; @@ -1716,19 +1832,16 @@ test(".delegate()/.undelegate()", function() { jQuery("#body").undelegate("div", "submit"); // Test binding with a different context - var clicked = 0, container = jQuery("#main")[0]; - jQuery("#main").delegate("#foo", "click", function(e){ clicked++; }); + var clicked = 0, container = jQuery("#qunit-fixture")[0]; + jQuery("#qunit-fixture").delegate("#foo", "click", function(e){ clicked++; }); jQuery("div").trigger("click"); jQuery("#foo").trigger("click"); - jQuery("#main").trigger("click"); + jQuery("#qunit-fixture").trigger("click"); jQuery("body").trigger("click"); equals( clicked, 2, "delegate with a context" ); - // Make sure the event is actually stored on the context - ok( jQuery._data(container, "events").live, "delegate with a context" ); - // Test unbinding with a different context - jQuery("#main").undelegate("#foo", "click"); + jQuery("#qunit-fixture").undelegate("#foo", "click"); jQuery("#foo").trigger("click"); equals( clicked, 2, "undelegate with a context"); @@ -2122,6 +2235,156 @@ test("custom events with colons (#3533, #8272)", function() { }); +test(".on and .off", function() { + expect(9); + var counter, mixfn; + + jQuery( '<div id="onandoff"><p>on<b>and</b>off</p><div>worked<em>or</em>borked?</div></div>' ).appendTo( 'body' ); + + // Simple case + jQuery( "#onandoff" ) + .on( "whip", function() { + ok( true, "whipped it good" ); + }) + .trigger( "whip" ) + .off(); + + // Direct events only + counter = 0; + jQuery( "#onandoff b" ) + .on( "click", 5, function( e, trig ) { + counter += e.data + (trig || 9); // twice, 5+9+5+17=36 + }) + .one( "click", 7, function( e, trig ) { + counter += e.data + (trig || 11); // once, 7+11=18 + }) + .click() + .trigger( "click", 17 ) + .off( "click" ); + equals( counter, 54, "direct event bindings with data" ); + + // Delegated events only + counter = 0; + jQuery( "#onandoff" ) + .on( "click", "em", 5, function( e, trig ) { + counter += e.data + (trig || 9); // twice, 5+9+5+17=36 + }) + .one( "click", "em", 7, function( e, trig ) { + counter += e.data + (trig || 11); // once, 7+11=18 + }) + .find("em") + .click() + .trigger( "click", 17 ) + .end() + .off( "click", "em" ); + equals( counter, 54, "delegated event bindings with data" ); + + + // Mixed event bindings and types + counter = 0; + mixfn = function(e, trig) { + counter += (e.data || 0) + (trig || 1); + }; + jQuery( "#onandoff" ) + .on( "click clack cluck", "em", 2, mixfn ) + .on( "cluck", "b", 7, mixfn ) + .on( "cluck", mixfn ) + .trigger( "what!" ) + .each( function() { + equals( counter, 0, "nothing triggered yet" ); + }) + .find( "em" ) + .one( "cluck", 3, mixfn ) + .trigger( "cluck", 8 ) // 3+8 2+8 + 0+8 = 29 + .off() + .trigger( "cluck", 9 ) // 2+9 + 0+9 = 20 + .end() + .each( function() { + equals( counter, 49, "after triggering em element" ); + }) + .off( "cluck", function(){} ) // shouldn't remove anything + .trigger( "cluck", 2 ) // 0+2 = 2 + .each( function() { + equals( counter, 51, "after triggering #onandoff cluck" ); + }) + .find( "b" ) + .on( "click", 95, mixfn ) + .on( "clack", "p", 97, mixfn ) + .one( "cluck", 3, mixfn ) + .trigger( "quack", 19 ) // 0 + .off( "click clack cluck" ) + .end() + .each( function() { + equals( counter, 51, "after triggering b" ); + }) + .trigger( "cluck", 3 ) // 0+3 = 3 + .off( "clack", "em", mixfn ) + .find( "em" ) + .trigger( "clack" ) // 0 + .end() + .each( function() { + equals( counter, 54, "final triggers" ); + }) + .off( "click cluck" ); + + // We should have removed all the event handlers ... kinda hacky way to check this + var data = jQuery.data[ jQuery( "#onandoff" )[0].expando ] || {}; + equals( data.events, undefined, "no events left" ); + + jQuery("#onandoff").remove(); +}); + +test("delegated events quickIs", function() { + expect(23); + var markup = jQuery( + '<div>'+ + '<p class="D">'+ + 'dead<b devo="cool">beat</b>club'+ + '</p>'+ + '<q id="famous">'+ + 'worked<em>or</em>borked?<em></em>'+ + '</q>'+ + '</div>' + ), + str, + check = function(el, expect){ + str = ""; + markup.find( el ).trigger( "blink" ); + equals( str, expect, "On " + el ); + }, + func = function(e){ + var tag = this.nodeName.toLowerCase(); + str += (str && " ") + tag + "|" + e.handleObj.selector; + ok( e.handleObj.quick, "Selector "+ e.handleObj.selector + " on " + tag + " is a quickIs case" ); + }; + + // tag#id.class[name=value] + markup + .appendTo( "body" ) + .on( "blink", "em", func ) + .on( "blink", ".D", func ) + .on( "blink", ".d", func ) + .on( "blink", "p.d", func ) + .on( "blink", "[devo=cool]", func ) + .on( "blink", "[devo='NO']", func ) + .on( "blink", "#famous", func ) + .on( "blink", "em:empty", func ) + .on( "blink", ":first-child", func ) + .on( "blink", "em:last-child", func ); + + check( "[devo=cool]", "b|[devo=cool] p|.D p|:first-child" ); + check( "[devo='']", "" ); + check( "p", "p|.D p|:first-child" ); + check( "b", "b|[devo=cool] p|.D p|:first-child" ); + check( "em", "em|em q|#famous em|em em|em:empty em|em:last-child q|#famous" ); + + markup.find( "b" ).attr( "devo", "NO" ); + check( "b", "b|[devo='NO'] p|.D p|:first-child" ); + + markup.remove(); +}); + + (function(){ // This code must be run before DOM ready! var notYetReady, noEarlyExecution, |