Merge branch 'fix_suite_fails' of https://github.com/timmywil/jquery into timmywil...
[jquery.git] / test / unit / event.js
blob6871842943d791337ffbe99b75814ebd01c0b9eb
1 module("event", { teardown: moduleTeardown });
3 test("null or undefined handler", function() {
4         expect(2);
5         // Supports Fixes bug #7229
6         try {
7                 jQuery("#firstp").click(null);
8                 ok(true, "Passing a null handler will not throw an exception");
9         } catch (e) {}
11         try {
12                 jQuery("#firstp").click(undefined);
13                 ok(true, "Passing an undefined handler will not throw an exception");
14         } catch (e) {}
15 });
17 test("bind(), with data", function() {
18         expect(3);
19         var handler = function(event) {
20                 ok( event.data, "bind() with data, check passed data exists" );
21                 equals( event.data.foo, "bar", "bind() with data, Check value of passed data" );
22         };
23         jQuery("#firstp").bind("click", {foo: "bar"}, handler).click().unbind("click", handler);
25         ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
26 });
28 test("click(), with data", function() {
29         expect(3);
30         var handler = function(event) {
31                 ok( event.data, "bind() with data, check passed data exists" );
32                 equals( event.data.foo, "bar", "bind() with data, Check value of passed data" );
33         };
34         jQuery("#firstp").click({foo: "bar"}, handler).click().unbind("click", handler);
36         ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." );
37 });
39 test("bind(), with data, trigger with data", function() {
40         expect(4);
41         var handler = function(event, data) {
42                 ok( event.data, "check passed data exists" );
43                 equals( event.data.foo, "bar", "Check value of passed data" );
44                 ok( data, "Check trigger data" );
45                 equals( data.bar, "foo", "Check value of trigger data" );
46         };
47         jQuery("#firstp").bind("click", {foo: "bar"}, handler).trigger("click", [{bar: "foo"}]).unbind("click", handler);
48 });
50 test("bind(), multiple events at once", function() {
51         expect(2);
52         var clickCounter = 0,
53                 mouseoverCounter = 0;
54         var handler = function(event) {
55                 if (event.type == "click")
56                         clickCounter += 1;
57                 else if (event.type == "mouseover")
58                         mouseoverCounter += 1;
59         };
60         jQuery("#firstp").bind("click mouseover", handler).trigger("click").trigger("mouseover");
61         equals( clickCounter, 1, "bind() with multiple events at once" );
62         equals( mouseoverCounter, 1, "bind() with multiple events at once" );
63 });
65 test("bind(), multiple events at once and namespaces", function() {
66         expect(7);
68         var cur, obj = {};
70         var div = jQuery("<div/>").bind("focusin.a", function(e) {
71                 equals( e.type, cur, "Verify right single event was fired." );
72         });
74         cur = "focusin";
75         div.trigger("focusin.a");
77         // manually clean up detached elements
78         div.remove();
80         div = jQuery("<div/>").bind("click mouseover", obj, function(e) {
81                 equals( e.type, cur, "Verify right multi event was fired." );
82                 equals( e.data, obj, "Make sure the data came in correctly." );
83         });
85         cur = "click";
86         div.trigger("click");
88         cur = "mouseover";
89         div.trigger("mouseover");
91         // manually clean up detached elements
92         div.remove();
94         div = jQuery("<div/>").bind("focusin.a focusout.b", function(e) {
95                 equals( e.type, cur, "Verify right multi event was fired." );
96         });
98         cur = "focusin";
99         div.trigger("focusin.a");
101         cur = "focusout";
102         div.trigger("focusout.b");
104         // manually clean up detached elements
105         div.remove();
108 test("bind(), namespace with special add", function() {
109         expect(24);
111         var div = jQuery("<div/>").bind("test", function(e) {
112                 ok( true, "Test event fired." );
113         });
115         var i = 0;
117         jQuery.event.special.test = {
118                 _default: function(e) {
119                         equals( this, document, "Make sure we're at the top of the chain." );
120                         equals( e.type, "test", "And that we're still dealing with a test event." );
121                         equals( e.target, div[0], "And that the target is correct." );
122                 },
123                 setup: function(){},
124                 teardown: function(){
125                         ok(true, "Teardown called.");
126                 },
127                 add: function( handleObj ) {
128                         var handler = handleObj.handler;
129                         handleObj.handler = function(e) {
130                                 e.xyz = ++i;
131                                 handler.apply( this, arguments );
132                         };
133                 },
134                 remove: function() {
135                         ok(true, "Remove called.");
136                 }
137         };
139         div.bind("test.a", {x: 1}, function(e) {
140                 ok( !!e.xyz, "Make sure that the data is getting passed through." );
141                 equals( e.data.x, 1, "Make sure data is attached properly." );
142         });
144         div.bind("test.b", {x: 2}, function(e) {
145                 ok( !!e.xyz, "Make sure that the data is getting passed through." );
146                 equals( e.data.x, 2, "Make sure data is attached properly." );
147         });
149         // Should trigger 5
150         div.trigger("test");
152         // Should trigger 2
153         div.trigger("test.a");
155         // Should trigger 2
156         div.trigger("test.b");
158         // Should trigger 4
159         div.unbind("test");
161         div = jQuery("<div/>").bind("test", function(e) {
162                 ok( true, "Test event fired." );
163         });
165         // Should trigger 2
166         div.appendTo("#main").remove();
168         delete jQuery.event.special.test;
171 test("bind(), no data", function() {
172         expect(1);
173         var handler = function(event) {
174                 ok ( !event.data, "Check that no data is added to the event object" );
175         };
176         jQuery("#firstp").bind("click", handler).trigger("click");
179 test("bind/one/unbind(Object)", function(){
180         expect(6);
182         var clickCounter = 0, mouseoverCounter = 0;
183         function handler(event) {
184                 if (event.type == "click")
185                         clickCounter++;
186                 else if (event.type == "mouseover")
187                         mouseoverCounter++;
188         };
190         function handlerWithData(event) {
191                 if (event.type == "click")
192                         clickCounter += event.data;
193                 else if (event.type == "mouseover")
194                         mouseoverCounter += event.data;
195         };
197         function trigger(){
198                 $elem.trigger("click").trigger("mouseover");
199         }
201         var $elem = jQuery("#firstp")
202                 // Regular bind
203                 .bind({
204                         click:handler,
205                         mouseover:handler
206                 })
207                 // Bind with data
208                 .one({
209                         click:handlerWithData,
210                         mouseover:handlerWithData
211                 }, 2 );
213         trigger();
215         equals( clickCounter, 3, "bind(Object)" );
216         equals( mouseoverCounter, 3, "bind(Object)" );
218         trigger();
219         equals( clickCounter, 4, "bind(Object)" );
220         equals( mouseoverCounter, 4, "bind(Object)" );
222         jQuery("#firstp").unbind({
223                 click:handler,
224                 mouseover:handler
225         });
227         trigger();
228         equals( clickCounter, 4, "bind(Object)" );
229         equals( mouseoverCounter, 4, "bind(Object)" );
232 test("live/die(Object), delegate/undelegate(String, Object)", function() {
233         expect(6);
235         var clickCounter = 0, mouseoverCounter = 0,
236                 $p = jQuery("#firstp"), $a = $p.find("a:first");
238         var events = {
239                 click: function( event ) {
240                         clickCounter += ( event.data || 1 );
241                 },
242                 mouseover: function( event ) {
243                         mouseoverCounter += ( event.data || 1 );
244                 }
245         };
247         function trigger() {
248                 $a.trigger("click").trigger("mouseover");
249         }
251         $a.live( events );
252         $p.delegate( "a", events, 2 );
254         trigger();
255         equals( clickCounter, 3, "live/delegate" );
256         equals( mouseoverCounter, 3, "live/delegate" );
258         $p.undelegate( "a", events );
260         trigger();
261         equals( clickCounter, 4, "undelegate" );
262         equals( mouseoverCounter, 4, "undelegate" );
264         $a.die( events );
266         trigger();
267         equals( clickCounter, 4, "die" );
268         equals( mouseoverCounter, 4, "die" );
271 test("live/delegate immediate propagation", function() {
272         expect(2);
274         var $p = jQuery("#firstp"), $a = $p.find("a:first"), lastClick;
276         lastClick = "";
277         $a.live( "click", function(e) {
278                 lastClick = "click1";
279                 e.stopImmediatePropagation();
280         });
281         $a.live( "click", function(e) {
282                 lastClick = "click2";
283         });
284         $a.trigger( "click" );
285         equals( lastClick, "click1", "live stopImmediatePropagation" );
286         $a.die( "click" );
288         lastClick = "";
289         $p.delegate( "a", "click", function(e) {
290                 lastClick = "click1";
291                 e.stopImmediatePropagation();
292         });
293         $p.delegate( "a", "click", function(e) {
294                 lastClick = "click2";
295         });
296         $a.trigger( "click" );
297         equals( lastClick, "click1", "delegate stopImmediatePropagation" );
298         $p.undelegate( "click" );
301 test("bind/delegate bubbling, isDefaultPrevented", function() {
302         expect(2);
303         var $anchor2 = jQuery( "#anchor2" ),
304                 $main = jQuery( "#main" ),
305                 fakeClick = function($jq) {
306                         // Use a native click so we don't get jQuery simulated bubbling
307                         if ( document.createEvent ) {
308                                 var e = document.createEvent( "MouseEvents" );
309                                 e.initEvent( "click", true, true );
310                                 $jq[0].dispatchEvent(e);
311                         }
312                         else if ( $jq[0].click ) {
313                                 $jq[0].click(); // IE
314                         }
315                 };
316         $anchor2.click(function(e) {
317                 e.preventDefault();
318         });
319         $main.delegate("#foo", "click", function(e) {
320                 var orig = e.originalEvent;
322                 if ( typeof(orig.defaultPrevented) === "boolean" || typeof(orig.returnValue) === "boolean" || orig.getPreventDefault ) {
323                         equals( e.isDefaultPrevented(), true, "isDefaultPrevented true passed to bubbled event" );
325                 } else {
326                         // Opera < 11 doesn't implement any interface we can use, so give it a pass
327                         ok( true, "isDefaultPrevented not supported by this browser, test skipped" );
328                 }
329         });
330         fakeClick( $anchor2 );
331         $anchor2.unbind( "click" );
332         $main.undelegate( "click" );
333         $anchor2.click(function(e) {
334                 // Let the default action occur
335         });
336         $main.delegate("#foo", "click", function(e) {
337                 equals( e.isDefaultPrevented(), false, "isDefaultPrevented false passed to bubbled event" );
338         });
339         fakeClick( $anchor2 );
340         $anchor2.unbind( "click" );
341         $main.undelegate( "click" );
344 test("bind(), iframes", function() {
345         // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
346         var doc = jQuery("#loadediframe").contents();
348         jQuery("div", doc).bind("click", function() {
349                 ok( true, "Binding to element inside iframe" );
350         }).click().unbind("click");
353 test("bind(), trigger change on select", function() {
354         expect(5);
355         var counter = 0;
356         function selectOnChange(event) {
357                 equals( event.data, counter++, "Event.data is not a global event object" );
358         };
359         jQuery("#form select").each(function(i){
360                 jQuery(this).bind("change", i, selectOnChange);
361         }).trigger("change");
364 test("bind(), namespaced events, cloned events", 18, function() {
365         var firstp = jQuery( "#firstp" );
367         firstp.bind("custom.test",function(e){
368                 ok(false, "Custom event triggered");
369         });
371         firstp.bind("click",function(e){
372                 ok(true, "Normal click triggered");
373                 equal( e.type + e.namespace, "click", "Check that only click events trigger this fn" );
374         });
376         firstp.bind("click.test",function(e){
377                 var check = "click";
378                 ok( true, "Namespaced click triggered" );
379                 if ( e.namespace ) {
380                         check += "test";
381                 }
382                 equal( e.type + e.namespace, check, "Check that only click/click.test events trigger this fn" );
383         });
385         //clone(true) element to verify events are cloned correctly
386         firstp = firstp.add( firstp.clone( true ).attr( "id", "firstp2" ).insertBefore( firstp ) );
388         // Trigger both bound fn (8)
389         firstp.trigger("click");
391         // Trigger one bound fn (4)
392         firstp.trigger("click.test");
394         // Remove only the one fn
395         firstp.unbind("click.test");
397         // Trigger the remaining fn (4)
398         firstp.trigger("click");
400         // Remove the remaining namespaced fn
401         firstp.unbind(".test");
403         // Try triggering the custom event (0)
404         firstp.trigger("custom");
406         // using contents will get comments regular, text, and comment nodes
407         jQuery("#nonnodes").contents().bind("tester", function () {
408                 equals(this.nodeType, 1, "Check node,textnode,comment bind just does real nodes" );
409         }).trigger("tester");
411         // Make sure events stick with appendTo'd elements (which are cloned) #2027
412         jQuery("<a href='#fail' class='test'>test</a>").click(function(){ return false; }).appendTo("#main");
413         ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" );
416 test("bind(), multi-namespaced events", function() {
417         expect(6);
419         var order = [
420                 "click.test.abc",
421                 "click.test.abc",
422                 "click.test",
423                 "click.test.abc",
424                 "click.test",
425                 "custom.test2"
426         ];
428         function check(name, msg){
429                 same(name, order.shift(), msg);
430         }
432         jQuery("#firstp").bind("custom.test",function(e){
433                 check("custom.test", "Custom event triggered");
434         });
436         jQuery("#firstp").bind("custom.test2",function(e){
437                 check("custom.test2", "Custom event triggered");
438         });
440         jQuery("#firstp").bind("click.test",function(e){
441                 check("click.test", "Normal click triggered");
442         });
444         jQuery("#firstp").bind("click.test.abc",function(e){
445                 check("click.test.abc", "Namespaced click triggered");
446         });
448         // Those would not trigger/unbind (#5303)
449         jQuery("#firstp").trigger("click.a.test");
450         jQuery("#firstp").unbind("click.a.test");
452         // Trigger both bound fn (1)
453         jQuery("#firstp").trigger("click.test.abc");
455         // Trigger one bound fn (1)
456         jQuery("#firstp").trigger("click.abc");
458         // Trigger two bound fn (2)
459         jQuery("#firstp").trigger("click.test");
461         // Remove only the one fn
462         jQuery("#firstp").unbind("click.abc");
464         // Trigger the remaining fn (1)
465         jQuery("#firstp").trigger("click");
467         // Remove the remaining fn
468         jQuery("#firstp").unbind(".test");
470         // Trigger the remaining fn (1)
471         jQuery("#firstp").trigger("custom");
474 test("bind(), with same function", function() {
475         expect(2)
477         var count = 0, func = function(){
478                 count++;
479         };
481         jQuery("#liveHandlerOrder").bind("foo.bar", func).bind("foo.zar", func);
482         jQuery("#liveHandlerOrder").trigger("foo.bar");
484         equals(count, 1, "Verify binding function with multiple namespaces." );
486         jQuery("#liveHandlerOrder").unbind("foo.bar", func).unbind("foo.zar", func);
487         jQuery("#liveHandlerOrder").trigger("foo.bar");
489         equals(count, 1, "Verify that removing events still work." );
492 test("bind(), make sure order is maintained", function() {
493         expect(1);
495         var elem = jQuery("#firstp"), log = [], check = [];
497         for ( var i = 0; i < 100; i++ ) (function(i){
498                 elem.bind( "click", function(){
499                         log.push( i );
500                 });
502                 check.push( i );
503         })(i);
505         elem.trigger("click");
507         equals( log.join(","), check.join(","), "Make sure order was maintained." );
509         elem.unbind("click");
512 test("bind(), with different this object", function() {
513         expect(4);
514         var thisObject = { myThis: true },
515                 data = { myData: true },
516                 handler1 = function( event ) {
517                         equals( this, thisObject, "bind() with different this object" );
518                 },
519                 handler2 = function( event ) {
520                         equals( this, thisObject, "bind() with different this object and data" );
521                         equals( event.data, data, "bind() with different this object and data" );
522                 };
524         jQuery("#firstp")
525                 .bind("click", jQuery.proxy(handler1, thisObject)).click().unbind("click", handler1)
526                 .bind("click", data, jQuery.proxy(handler2, thisObject)).click().unbind("click", handler2);
528         ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." );
531 test("bind(name, false), unbind(name, false)", function() {
532         expect(3);
534         var main = 0;
535         jQuery("#main").bind("click", function(e){ main++; });
536         jQuery("#ap").trigger("click");
537         equals( main, 1, "Verify that the trigger happened correctly." );
539         main = 0;
540         jQuery("#ap").bind("click", false);
541         jQuery("#ap").trigger("click");
542         equals( main, 0, "Verify that no bubble happened." );
544         main = 0;
545         jQuery("#ap").unbind("click", false);
546         jQuery("#ap").trigger("click");
547         equals( main, 1, "Verify that the trigger happened correctly." );
549         // manually clean up events from elements outside the fixture
550         jQuery("#main").unbind("click");
553 test("live(name, false), die(name, false)", function() {
554         expect(3);
556         var main = 0;
557         jQuery("#main").live("click", function(e){ main++; });
558         jQuery("#ap").trigger("click");
559         equals( main, 1, "Verify that the trigger happened correctly." );
561         main = 0;
562         jQuery("#ap").live("click", false);
563         jQuery("#ap").trigger("click");
564         equals( main, 0, "Verify that no bubble happened." );
566         main = 0;
567         jQuery("#ap").die("click", false);
568         jQuery("#ap").trigger("click");
569         equals( main, 1, "Verify that the trigger happened correctly." );
570         jQuery("#main").die("click");
573 test("delegate(selector, name, false), undelegate(selector, name, false)", function() {
574         expect(3);
576         var main = 0;
578         jQuery("#main").delegate("#ap", "click", function(e){ main++; });
579         jQuery("#ap").trigger("click");
580         equals( main, 1, "Verify that the trigger happened correctly." );
582         main = 0;
583         jQuery("#ap").delegate("#groups", "click", false);
584         jQuery("#groups").trigger("click");
585         equals( main, 0, "Verify that no bubble happened." );
587         main = 0;
588         jQuery("#ap").undelegate("#groups", "click", false);
589         jQuery("#groups").trigger("click");
590         equals( main, 1, "Verify that the trigger happened correctly." );
591         jQuery("#main").undelegate("#ap", "click");
594 test("bind()/trigger()/unbind() on plain object", function() {
595         expect( 7 );
597         var obj = {};
599         // Make sure it doesn't complain when no events are found
600         jQuery(obj).trigger("test");
602         // Make sure it doesn't complain when no events are found
603         jQuery(obj).unbind("test");
605         jQuery(obj).bind({
606                 test: function() {
607                         ok( true, "Custom event run." );
608                 },
609                 submit: function() {
610                         ok( true, "Custom submit event run." );
611                 }
612         });
614         var events = jQuery._data(obj, "events");
615         ok( events, "Object has events bound." );
616         equals( obj.events, undefined, "Events object on plain objects is not events" );
617         equals( obj.test, undefined, "Make sure that test event is not on the plain object." );
618         equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
620         // Should trigger 1
621         jQuery(obj).trigger("test");
622         jQuery(obj).trigger("submit");
624         jQuery(obj).unbind("test");
625         jQuery(obj).unbind("submit");
627         // Should trigger 0
628         jQuery(obj).trigger("test");
630         // Make sure it doesn't complain when no events are found
631         jQuery(obj).unbind("test");
633         equals( obj && obj[ jQuery.expando ] &&
634                         obj[ jQuery.expando ][ jQuery.expando ] &&
635                         obj[ jQuery.expando ][ jQuery.expando ].events, undefined, "Make sure events object is removed" );
638 test("unbind(type)", function() {
639         expect( 0 );
641         var $elem = jQuery("#firstp"),
642                 message;
644         function error(){
645                 ok( false, message );
646         }
648         message = "unbind passing function";
649         $elem.bind("error1", error).unbind("error1", error).triggerHandler("error1");
651         message = "unbind all from event";
652         $elem.bind("error1", error).unbind("error1").triggerHandler("error1");
654         message = "unbind all";
655         $elem.bind("error1", error).unbind().triggerHandler("error1");
657         message = "unbind many with function";
658         $elem.bind("error1 error2",error)
659                 .unbind("error1 error2", error )
660                 .trigger("error1").triggerHandler("error2");
662         message = "unbind many"; // #3538
663         $elem.bind("error1 error2", error)
664                 .unbind("error1 error2")
665                 .trigger("error1").triggerHandler("error2");
667         message = "unbind without a type or handler";
668         $elem.bind("error1 error2.test",error)
669                 .unbind()
670                 .trigger("error1").triggerHandler("error2");
673 test("unbind(eventObject)", function() {
674         expect(4);
676         var $elem = jQuery("#firstp"),
677                 num;
679         function assert( expected ){
680                 num = 0;
681                 $elem.trigger("foo").triggerHandler("bar");
682                 equals( num, expected, "Check the right handlers are triggered" );
683         }
685         $elem
686                 // This handler shouldn't be unbound
687                 .bind("foo", function(){
688                         num += 1;
689                 })
690                 .bind("foo", function(e){
691                         $elem.unbind( e )
692                         num += 2;
693                 })
694                 // Neither this one
695                 .bind("bar", function(){
696                         num += 4;
697                 });
699         assert( 7 );
700         assert( 5 );
702         $elem.unbind("bar");
703         assert( 1 );
705         $elem.unbind();
706         assert( 0 );
709 test("hover()", function() {
710         var times = 0,
711                 handler1 = function( event ) { ++times; },
712                 handler2 = function( event ) { ++times; };
714         jQuery("#firstp")
715                 .hover(handler1, handler2)
716                 .mouseenter().mouseleave()
717                 .unbind("mouseenter", handler1)
718                 .unbind("mouseleave", handler2)
719                 .hover(handler1)
720                 .mouseenter().mouseleave()
721                 .unbind("mouseenter mouseleave", handler1)
722                 .mouseenter().mouseleave();
724         equals( times, 4, "hover handlers fired" );
727 test("mouseover triggers mouseenter", function() {
728         expect(1);
730         var count = 0,
731                 elem = jQuery("<a />");
732         elem.mouseenter(function () {
733           count++;
734         });
735         elem.trigger("mouseover");
736         equals(count, 1, "make sure mouseover triggers a mouseenter" );
738         elem.remove();
741 test("trigger() shortcuts", function() {
742         expect(6);
744         var elem = jQuery("<li><a href='#'>Change location</a></li>").prependTo("#firstUL");
745         elem.find("a").bind("click", function() {
746                 var close = jQuery("spanx", this); // same with jQuery(this).find("span");
747                 equals( close.length, 0, "Context element does not exist, length must be zero" );
748                 ok( !close[0], "Context element does not exist, direct access to element must return undefined" );
749                 return false;
750         }).click();
752         // manually clean up detached elements
753         elem.remove();
755         jQuery("#check1").click(function() {
756                 ok( true, "click event handler for checkbox gets fired twice, see #815" );
757         }).click();
759         var counter = 0;
760         jQuery("#firstp")[0].onclick = function(event) {
761                 counter++;
762         };
763         jQuery("#firstp").click();
764         equals( counter, 1, "Check that click, triggers onclick event handler also" );
766         var clickCounter = 0;
767         jQuery("#simon1")[0].onclick = function(event) {
768                 clickCounter++;
769         };
770         jQuery("#simon1").click();
771         equals( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" );
773         elem = jQuery("<img />").load(function(){
774                 ok( true, "Trigger the load event, using the shortcut .load() (#2819)");
775         }).load();
777         // manually clean up detached elements
778         elem.remove();
780         // test that special handlers do not blow up with VML elements (#7071)
781         jQuery('<xml:namespace ns="urn:schemas-microsoft-com:vml" prefix="v" />').appendTo('head');
782         jQuery('<v:oval id="oval" style="width:100pt;height:75pt;" fillcolor="red"> </v:oval>').appendTo('#form');
783         jQuery("#oval").click().keydown();
786 test("trigger() bubbling", function() {
787         expect(17);
789         var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
791         jQuery(window).bind("click", function(e){ win++; });
792         jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } });
793         jQuery("html").bind("click", function(e){ html++; });
794         jQuery("body").bind("click", function(e){ body++; });
795         jQuery("#main").bind("click", function(e){ main++; });
796         jQuery("#ap").bind("click", function(){ ap++; return false; });
798         jQuery("html").trigger("click");
799         equals( win, 1, "HTML bubble" );
800         equals( doc, 1, "HTML bubble" );
801         equals( html, 1, "HTML bubble" );
803         jQuery("body").trigger("click");
804         equals( win, 2, "Body bubble" );
805         equals( doc, 2, "Body bubble" );
806         equals( html, 2, "Body bubble" );
807         equals( body, 1, "Body bubble" );
809         jQuery("#main").trigger("click");
810         equals( win, 3, "Main bubble" );
811         equals( doc, 3, "Main bubble" );
812         equals( html, 3, "Main bubble" );
813         equals( body, 2, "Main bubble" );
814         equals( main, 1, "Main bubble" );
816         jQuery("#ap").trigger("click");
817         equals( doc, 3, "ap bubble" );
818         equals( html, 3, "ap bubble" );
819         equals( body, 2, "ap bubble" );
820         equals( main, 1, "ap bubble" );
821         equals( ap, 1, "ap bubble" );
823         // manually clean up events from elements outside the fixture
824         jQuery(document).unbind("click");
825         jQuery("html, body, #main").unbind("click");
828 test("trigger(type, [data], [fn])", function() {
829         expect(14);
831         var handler = function(event, a, b, c) {
832                 equals( event.type, "click", "check passed data" );
833                 equals( a, 1, "check passed data" );
834                 equals( b, "2", "check passed data" );
835                 equals( c, "abc", "check passed data" );
836                 return "test";
837         };
839         var $elem = jQuery("#firstp");
841         // Simulate a "native" click
842         $elem[0].click = function(){
843                 ok( true, "Native call was triggered" );
844         };
846         // Triggers handlrs and native
847         // Trigger 5
848         $elem.bind("click", handler).trigger("click", [1, "2", "abc"]);
850         // Simulate a "native" click
851         $elem[0].click = function(){
852                 ok( false, "Native call was triggered" );
853         };
855         // Trigger only the handlers (no native)
856         // Triggers 5
857         equals( $elem.triggerHandler("click", [1, "2", "abc"]), "test", "Verify handler response" );
859         var pass = true;
860         try {
861                 jQuery("#form input:first").hide().trigger("focus");
862         } catch(e) {
863                 pass = false;
864         }
865         ok( pass, "Trigger focus on hidden element" );
867         pass = true;
868         try {
869                 jQuery("#main table:first").bind("test:test", function(){}).trigger("test:test");
870         } catch (e) {
871                 pass = false;
872         }
873         ok( pass, "Trigger on a table with a colon in the even type, see #3533" );
875         var form = jQuery("<form action=''></form>").appendTo("body");
877         // Make sure it can be prevented locally
878         form.submit(function(){
879                 ok( true, "Local bind still works." );
880                 return false;
881         });
883         // Trigger 1
884         form.trigger("submit");
886         form.unbind("submit");
888         jQuery(document).submit(function(){
889                 ok( true, "Make sure bubble works up to document." );
890                 return false;
891         });
893         // Trigger 1
894         form.trigger("submit");
896         jQuery(document).unbind("submit");
898         form.remove();
901 test("jQuery.Event.currentTarget", function(){
904 test("trigger(eventObject, [data], [fn])", function() {
905         expect(25);
907         var $parent = jQuery("<div id='par' />").hide().appendTo("body"),
908                 $child = jQuery("<p id='child'>foo</p>").appendTo( $parent );
910         var event = jQuery.Event("noNew");
911         ok( event != window, "Instantiate jQuery.Event without the 'new' keyword" );
912         equals( event.type, "noNew", "Verify its type" );
914         equals( event.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
915         equals( event.isPropagationStopped(), false, "Verify isPropagationStopped" );
916         equals( event.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
918         event.preventDefault();
919         equals( event.isDefaultPrevented(), true, "Verify isDefaultPrevented" );
920         event.stopPropagation();
921         equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
923         event.isPropagationStopped = function(){ return false };
924         event.stopImmediatePropagation();
925         equals( event.isPropagationStopped(), true, "Verify isPropagationStopped" );
926         equals( event.isImmediatePropagationStopped(), true, "Verify isPropagationStopped" );
928         $parent.bind("foo",function(e){
929                 // Tries bubbling
930                 equals( e.type, "foo", "Verify event type when passed passing an event object" );
931                 equals( e.target.id, "child", "Verify event.target when passed passing an event object" );
932                 equals( e.currentTarget.id, "par", "Verify event.target when passed passing an event object" );
933                 equals( e.secret, "boo!", "Verify event object's custom attribute when passed passing an event object" );
934         });
936         // test with an event object
937         event = new jQuery.Event("foo");
938         event.secret = "boo!";
939         $child.trigger(event);
941         // test with a literal object
942         $child.trigger({type: "foo", secret: "boo!"});
944         $parent.unbind();
946         function error(){
947                 ok( false, "This assertion shouldn't be reached");
948         }
950         $parent.bind("foo", error );
952         $child.bind("foo",function(e, a, b, c ){
953                 equals( arguments.length, 4, "Check arguments length");
954                 equals( a, 1, "Check first custom argument");
955                 equals( b, 2, "Check second custom argument");
956                 equals( c, 3, "Check third custom argument");
958                 equals( e.isDefaultPrevented(), false, "Verify isDefaultPrevented" );
959                 equals( e.isPropagationStopped(), false, "Verify isPropagationStopped" );
960                 equals( e.isImmediatePropagationStopped(), false, "Verify isImmediatePropagationStopped" );
962                 // Skips both errors
963                 e.stopImmediatePropagation();
965                 return "result";
966         });
968         // We should add this back in when we want to test the order
969         // in which event handlers are iterated.
970         //$child.bind("foo", error );
972         event = new jQuery.Event("foo");
973         $child.trigger( event, [1,2,3] ).unbind();
974         equals( event.result, "result", "Check event.result attribute");
976         // Will error if it bubbles
977         $child.triggerHandler("foo");
979         $child.unbind();
980         $parent.unbind().remove();
983 test("jQuery.Event( type, props )", function() {
985         expect(4);
987         var event = jQuery.Event( "keydown", { keyCode: 64 }),
988                         handler = function( event ) {
989                                 ok( "keyCode" in event, "Special property 'keyCode' exists" );
990                                 equal( event.keyCode, 64, "event.keyCode has explicit value '64'" );
991                         };
993         // Supports jQuery.Event implementation
994         equal( event.type, "keydown", "Verify type" );
996         ok( "keyCode" in event, "Special 'keyCode' property exists" );
998         jQuery("body").bind( "keydown", handler ).trigger( event );
1000         jQuery("body").unbind( "keydown" );
1004 test("jQuery.Event.currentTarget", function(){
1005         expect(1);
1007         var counter = 0,
1008                 $elem = jQuery("<button>a</button>").click(function(e){
1009                 equals( e.currentTarget, this, "Check currentTarget on "+(counter++?"native":"fake") +" event" );
1010         });
1012         // Fake event
1013         $elem.trigger("click");
1015         // Cleanup
1016         $elem.unbind();
1019 test("toggle(Function, Function, ...)", function() {
1020         expect(16);
1022         var count = 0,
1023                 fn1 = function(e) { count++; },
1024                 fn2 = function(e) { count--; },
1025                 preventDefault = function(e) { e.preventDefault() },
1026                 link = jQuery("#mark");
1027         link.click(preventDefault).click().toggle(fn1, fn2).click().click().click().click().click();
1028         equals( count, 1, "Check for toggle(fn, fn)" );
1030         jQuery("#firstp").toggle(function () {
1031                 equals(arguments.length, 4, "toggle correctly passes through additional triggered arguments, see #1701" )
1032         }, function() {}).trigger("click", [ 1, 2, 3 ]);
1034         var first = 0;
1035         jQuery("#simon1").one("click", function() {
1036                 ok( true, "Execute event only once" );
1037                 jQuery(this).toggle(function() {
1038                         equals( first++, 0, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
1039                 }, function() {
1040                         equals( first, 1, "toggle(Function,Function) assigned from within one('xxx'), see #1054" );
1041                 });
1042                 return false;
1043         }).click().click().click();
1045         var turn = 0;
1046         var fns = [
1047                 function(){
1048                         turn = 1;
1049                 },
1050                 function(){
1051                         turn = 2;
1052                 },
1053                 function(){
1054                         turn = 3;
1055                 }
1056         ];
1058         var $div = jQuery("<div>&nbsp;</div>").toggle( fns[0], fns[1], fns[2] );
1059         $div.click();
1060         equals( turn, 1, "Trying toggle with 3 functions, attempt 1 yields 1");
1061         $div.click();
1062         equals( turn, 2, "Trying toggle with 3 functions, attempt 2 yields 2");
1063         $div.click();
1064         equals( turn, 3, "Trying toggle with 3 functions, attempt 3 yields 3");
1065         $div.click();
1066         equals( turn, 1, "Trying toggle with 3 functions, attempt 4 yields 1");
1067         $div.click();
1068         equals( turn, 2, "Trying toggle with 3 functions, attempt 5 yields 2");
1070         $div.unbind("click",fns[0]);
1071         var data = jQuery._data( $div[0], "events" );
1072         ok( !data, "Unbinding one function from toggle unbinds them all");
1074         // manually clean up detached elements
1075         $div.remove();
1077         // Test Multi-Toggles
1078         var a = [], b = [];
1079         $div = jQuery("<div/>");
1080         $div.toggle(function(){ a.push(1); }, function(){ a.push(2); });
1081         $div.click();
1082         same( a, [1], "Check that a click worked." );
1084         $div.toggle(function(){ b.push(1); }, function(){ b.push(2); });
1085         $div.click();
1086         same( a, [1,2], "Check that a click worked with a second toggle." );
1087         same( b, [1], "Check that a click worked with a second toggle." );
1089         $div.click();
1090         same( a, [1,2,1], "Check that a click worked with a second toggle, second click." );
1091         same( b, [1,2], "Check that a click worked with a second toggle, second click." );
1093         // manually clean up detached elements
1094         $div.remove();
1097 test(".live()/.die()", function() {
1098         expect(66);
1100         var submit = 0, div = 0, livea = 0, liveb = 0;
1102         jQuery("div").live("submit", function(){ submit++; return false; });
1103         jQuery("div").live("click", function(){ div++; });
1104         jQuery("div#nothiddendiv").live("click", function(){ livea++; });
1105         jQuery("div#nothiddendivchild").live("click", function(){ liveb++; });
1107         // Nothing should trigger on the body
1108         jQuery("body").trigger("click");
1109         equals( submit, 0, "Click on body" );
1110         equals( div, 0, "Click on body" );
1111         equals( livea, 0, "Click on body" );
1112         equals( liveb, 0, "Click on body" );
1114         // This should trigger two events
1115         submit = 0, div = 0, livea = 0, liveb = 0;
1116         jQuery("div#nothiddendiv").trigger("click");
1117         equals( submit, 0, "Click on div" );
1118         equals( div, 1, "Click on div" );
1119         equals( livea, 1, "Click on div" );
1120         equals( liveb, 0, "Click on div" );
1122         // This should trigger three events (w/ bubbling)
1123         submit = 0, div = 0, livea = 0, liveb = 0;
1124         jQuery("div#nothiddendivchild").trigger("click");
1125         equals( submit, 0, "Click on inner div" );
1126         equals( div, 2, "Click on inner div" );
1127         equals( livea, 1, "Click on inner div" );
1128         equals( liveb, 1, "Click on inner div" );
1130         // This should trigger one submit
1131         submit = 0, div = 0, livea = 0, liveb = 0;
1132         jQuery("div#nothiddendivchild").trigger("submit");
1133         equals( submit, 1, "Submit on div" );
1134         equals( div, 0, "Submit on div" );
1135         equals( livea, 0, "Submit on div" );
1136         equals( liveb, 0, "Submit on div" );
1138         // Make sure no other events were removed in the process
1139         submit = 0, div = 0, livea = 0, liveb = 0;
1140         jQuery("div#nothiddendivchild").trigger("click");
1141         equals( submit, 0, "die Click on inner div" );
1142         equals( div, 2, "die Click on inner div" );
1143         equals( livea, 1, "die Click on inner div" );
1144         equals( liveb, 1, "die Click on inner div" );
1146         // Now make sure that the removal works
1147         submit = 0, div = 0, livea = 0, liveb = 0;
1148         jQuery("div#nothiddendivchild").die("click");
1149         jQuery("div#nothiddendivchild").trigger("click");
1150         equals( submit, 0, "die Click on inner div" );
1151         equals( div, 2, "die Click on inner div" );
1152         equals( livea, 1, "die Click on inner div" );
1153         equals( liveb, 0, "die Click on inner div" );
1155         // Make sure that the click wasn't removed too early
1156         submit = 0, div = 0, livea = 0, liveb = 0;
1157         jQuery("div#nothiddendiv").trigger("click");
1158         equals( submit, 0, "die Click on inner div" );
1159         equals( div, 1, "die Click on inner div" );
1160         equals( livea, 1, "die Click on inner div" );
1161         equals( liveb, 0, "die Click on inner div" );
1163         // Make sure that stopPropgation doesn't stop live events
1164         submit = 0, div = 0, livea = 0, liveb = 0;
1165         jQuery("div#nothiddendivchild").live("click", function(e){ liveb++; e.stopPropagation(); });
1166         jQuery("div#nothiddendivchild").trigger("click");
1167         equals( submit, 0, "stopPropagation Click on inner div" );
1168         equals( div, 1, "stopPropagation Click on inner div" );
1169         equals( livea, 0, "stopPropagation Click on inner div" );
1170         equals( liveb, 1, "stopPropagation Click on inner div" );
1172         // Make sure click events only fire with primary click
1173         submit = 0, div = 0, livea = 0, liveb = 0;
1174         var event = jQuery.Event("click");
1175         event.button = 1;
1176         jQuery("div#nothiddendiv").trigger(event);
1178         equals( livea, 0, "live secondary click" );
1180         jQuery("div#nothiddendivchild").die("click");
1181         jQuery("div#nothiddendiv").die("click");
1182         jQuery("div").die("click");
1183         jQuery("div").die("submit");
1185         // Test binding with a different context
1186         var clicked = 0, container = jQuery("#main")[0];
1187         jQuery("#foo", container).live("click", function(e){ clicked++; });
1188         jQuery("div").trigger("click");
1189         jQuery("#foo").trigger("click");
1190         jQuery("#main").trigger("click");
1191         jQuery("body").trigger("click");
1192         equals( clicked, 2, "live with a context" );
1194         // Make sure the event is actually stored on the context
1195         ok( jQuery._data(container, "events").live, "live with a context" );
1197         // Test unbinding with a different context
1198         jQuery("#foo", container).die("click");
1199         jQuery("#foo").trigger("click");
1200         equals( clicked, 2, "die with a context");
1202         // Test binding with event data
1203         jQuery("#foo").live("click", true, function(e){ equals( e.data, true, "live with event data" ); });
1204         jQuery("#foo").trigger("click").die("click");
1206         // Test binding with trigger data
1207         jQuery("#foo").live("click", function(e, data){ equals( data, true, "live with trigger data" ); });
1208         jQuery("#foo").trigger("click", true).die("click");
1210         // Test binding with different this object
1211         jQuery("#foo").live("click", jQuery.proxy(function(e){ equals( this.foo, "bar", "live with event scope" ); }, { foo: "bar" }));
1212         jQuery("#foo").trigger("click").die("click");
1214         // Test binding with different this object, event data, and trigger data
1215         jQuery("#foo").live("click", true, jQuery.proxy(function(e, data){
1216                 equals( e.data, true, "live with with different this object, event data, and trigger data" );
1217                 equals( this.foo, "bar", "live with with different this object, event data, and trigger data" );
1218                 equals( data, true, "live with with different this object, event data, and trigger data")
1219         }, { foo: "bar" }));
1220         jQuery("#foo").trigger("click", true).die("click");
1222         // Verify that return false prevents default action
1223         jQuery("#anchor2").live("click", function(){ return false; });
1224         var hash = window.location.hash;
1225         jQuery("#anchor2").trigger("click");
1226         equals( window.location.hash, hash, "return false worked" );
1227         jQuery("#anchor2").die("click");
1229         // Verify that .preventDefault() prevents default action
1230         jQuery("#anchor2").live("click", function(e){ e.preventDefault(); });
1231         var hash = window.location.hash;
1232         jQuery("#anchor2").trigger("click");
1233         equals( window.location.hash, hash, "e.preventDefault() worked" );
1234         jQuery("#anchor2").die("click");
1236         // Test binding the same handler to multiple points
1237         var called = 0;
1238         function callback(){ called++; return false; }
1240         jQuery("#nothiddendiv").live("click", callback);
1241         jQuery("#anchor2").live("click", callback);
1243         jQuery("#nothiddendiv").trigger("click");
1244         equals( called, 1, "Verify that only one click occurred." );
1246         called = 0;
1247         jQuery("#anchor2").trigger("click");
1248         equals( called, 1, "Verify that only one click occurred." );
1250         // Make sure that only one callback is removed
1251         jQuery("#anchor2").die("click", callback);
1253         called = 0;
1254         jQuery("#nothiddendiv").trigger("click");
1255         equals( called, 1, "Verify that only one click occurred." );
1257         called = 0;
1258         jQuery("#anchor2").trigger("click");
1259         equals( called, 0, "Verify that no click occurred." );
1261         // Make sure that it still works if the selector is the same,
1262         // but the event type is different
1263         jQuery("#nothiddendiv").live("foo", callback);
1265         // Cleanup
1266         jQuery("#nothiddendiv").die("click", callback);
1268         called = 0;
1269         jQuery("#nothiddendiv").trigger("click");
1270         equals( called, 0, "Verify that no click occurred." );
1272         called = 0;
1273         jQuery("#nothiddendiv").trigger("foo");
1274         equals( called, 1, "Verify that one foo occurred." );
1276         // Cleanup
1277         jQuery("#nothiddendiv").die("foo", callback);
1279         // Make sure we don't loose the target by DOM modifications
1280         // after the bubble already reached the liveHandler
1281         var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("<span></span>").get(0);
1283         jQuery("#nothiddendivchild").live("click", function(e){ jQuery("#nothiddendivchild").html(""); });
1284         jQuery("#nothiddendivchild").live("click", function(e){ if(e.target) {livec++;} });
1286         jQuery("#nothiddendiv span").click();
1287         equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
1288         equals( livec, 1, "Verify that second handler occurred even with nuked target." );
1290         // Cleanup
1291         jQuery("#nothiddendivchild").die("click");
1293         // Verify that .live() ocurs and cancel buble in the same order as
1294         // we would expect .bind() and .click() without delegation
1295         var lived = 0, livee = 0;
1297         // bind one pair in one order
1298         jQuery("span#liveSpan1 a").live("click", function(){ lived++; return false; });
1299         jQuery("span#liveSpan1").live("click", function(){ livee++; });
1301         jQuery("span#liveSpan1 a").click();
1302         equals( lived, 1, "Verify that only one first handler occurred." );
1303         equals( livee, 0, "Verify that second handler doesn't." );
1305         // and one pair in inverse
1306         jQuery("span#liveSpan2").live("click", function(){ livee++; });
1307         jQuery("span#liveSpan2 a").live("click", function(){ lived++; return false; });
1309         lived = 0;
1310         livee = 0;
1311         jQuery("span#liveSpan2 a").click();
1312         equals( lived, 1, "Verify that only one first handler occurred." );
1313         equals( livee, 0, "Verify that second handler doesn't." );
1315         // Cleanup
1316         jQuery("span#liveSpan1 a").die("click")
1317         jQuery("span#liveSpan1").die("click");
1318         jQuery("span#liveSpan2 a").die("click");
1319         jQuery("span#liveSpan2").die("click");
1321         // Test this, target and currentTarget are correct
1322         jQuery("span#liveSpan1").live("click", function(e){
1323                 equals( this.id, "liveSpan1", "Check the this within a live handler" );
1324                 equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a live handler" );
1325                 equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a live handler" );
1326         });
1328         jQuery("span#liveSpan1 a").click();
1330         jQuery("span#liveSpan1").die("click");
1332         // Work with deep selectors
1333         livee = 0;
1335         function clickB(){ livee++; }
1337         jQuery("#nothiddendiv div").live("click", function(){ livee++; });
1338         jQuery("#nothiddendiv div").live("click", clickB);
1339         jQuery("#nothiddendiv div").live("mouseover", function(){ livee++; });
1341         equals( livee, 0, "No clicks, deep selector." );
1343         livee = 0;
1344         jQuery("#nothiddendivchild").trigger("click");
1345         equals( livee, 2, "Click, deep selector." );
1347         livee = 0;
1348         jQuery("#nothiddendivchild").trigger("mouseover");
1349         equals( livee, 1, "Mouseover, deep selector." );
1351         jQuery("#nothiddendiv div").die("mouseover");
1353         livee = 0;
1354         jQuery("#nothiddendivchild").trigger("click");
1355         equals( livee, 2, "Click, deep selector." );
1357         livee = 0;
1358         jQuery("#nothiddendivchild").trigger("mouseover");
1359         equals( livee, 0, "Mouseover, deep selector." );
1361         jQuery("#nothiddendiv div").die("click", clickB);
1363         livee = 0;
1364         jQuery("#nothiddendivchild").trigger("click");
1365         equals( livee, 1, "Click, deep selector." );
1367         jQuery("#nothiddendiv div").die("click");
1369         jQuery("#nothiddendiv div").live("blur", function(){
1370                 ok( true, "Live div trigger blur." );
1371         });
1373         jQuery("#nothiddendiv div").trigger("blur");
1375         jQuery("#nothiddendiv div").die("blur");
1378 test("die all bound events", function(){
1379         expect(1);
1381         var count = 0;
1382         var div = jQuery("div#nothiddendivchild");
1384         div.live("click submit", function(){ count++; });
1385         div.die();
1387         div.trigger("click");
1388         div.trigger("submit");
1390         equals( count, 0, "Make sure no events were triggered." );
1393 test("live with multiple events", function(){
1394         expect(1);
1396         var count = 0;
1397         var div = jQuery("div#nothiddendivchild");
1399         div.live("click submit", function(){ count++; });
1401         div.trigger("click");
1402         div.trigger("submit");
1404         equals( count, 2, "Make sure both the click and submit were triggered." );
1406         // manually clean up events from elements outside the fixture
1407         div.die();
1410 test("live with namespaces", function(){
1411         expect(12);
1413         var count1 = 0, count2 = 0;
1415         jQuery("#liveSpan1").live("foo.bar", function(e){
1416                 count1++;
1417         });
1419         jQuery("#liveSpan1").live("foo.zed", function(e){
1420                 count2++;
1421         });
1423         jQuery("#liveSpan1").trigger("foo.bar");
1424         equals( count1, 1, "Got live foo.bar" );
1425         equals( count2, 0, "Got live foo.bar" );
1427         count1 = 0, count2 = 0;
1429         jQuery("#liveSpan1").trigger("foo.zed");
1430         equals( count1, 0, "Got live foo.zed" );
1431         equals( count2, 1, "Got live foo.zed" );
1433         //remove one
1434         count1 = 0, count2 = 0;
1436         jQuery("#liveSpan1").die("foo.zed");
1437         jQuery("#liveSpan1").trigger("foo.bar");
1439         equals( count1, 1, "Got live foo.bar after dieing foo.zed" );
1440         equals( count2, 0, "Got live foo.bar after dieing foo.zed" );
1442         count1 = 0, count2 = 0;
1444         jQuery("#liveSpan1").trigger("foo.zed");
1445         equals( count1, 0, "Got live foo.zed" );
1446         equals( count2, 0, "Got live foo.zed" );
1448         //remove the other
1449         jQuery("#liveSpan1").die("foo.bar");
1451         count1 = 0, count2 = 0;
1453         jQuery("#liveSpan1").trigger("foo.bar");
1454         equals( count1, 0, "Did not respond to foo.bar after dieing it" );
1455         equals( count2, 0, "Did not respond to foo.bar after dieing it" );
1457         jQuery("#liveSpan1").trigger("foo.zed");
1458         equals( count1, 0, "Did not trigger foo.zed again" );
1459         equals( count2, 0, "Did not trigger foo.zed again" );
1462 test("live with change", function(){
1463         expect(8);
1465         var selectChange = 0, checkboxChange = 0;
1467         var select = jQuery("select[name='S1']")
1468         select.live("change", function() {
1469                 selectChange++;
1470         });
1472         var checkbox = jQuery("#check2"),
1473                 checkboxFunction = function(){
1474                         checkboxChange++;
1475                 }
1476         checkbox.live("change", checkboxFunction);
1478         // test click on select
1480         // second click that changed it
1481         selectChange = 0;
1482         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1483         select.trigger("change");
1484         equals( selectChange, 1, "Change on click." );
1486         // test keys on select
1487         selectChange = 0;
1488         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1489         select.trigger("change");
1490         equals( selectChange, 1, "Change on keyup." );
1492         // test click on checkbox
1493         checkbox.trigger("change");
1494         equals( checkboxChange, 1, "Change on checkbox." );
1496         // test blur/focus on text
1497         var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
1498         text.live("change", function() {
1499                 textChange++;
1500         });
1502         text.val(oldTextVal+"foo");
1503         text.trigger("change");
1504         equals( textChange, 1, "Change on text input." );
1506         text.val(oldTextVal);
1507         text.die("change");
1509         // test blur/focus on password
1510         var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
1511         password.live("change", function() {
1512                 passwordChange++;
1513         });
1515         password.val(oldPasswordVal + "foo");
1516         password.trigger("change");
1517         equals( passwordChange, 1, "Change on password input." );
1519         password.val(oldPasswordVal);
1520         password.die("change");
1522         // make sure die works
1524         // die all changes
1525         selectChange = 0;
1526         select.die("change");
1527         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1528         select.trigger("change");
1529         equals( selectChange, 0, "Die on click works." );
1531         selectChange = 0;
1532         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1533         select.trigger("change");
1534         equals( selectChange, 0, "Die on keyup works." );
1536         // die specific checkbox
1537         checkbox.die("change", checkboxFunction);
1538         checkbox.trigger("change");
1539         equals( checkboxChange, 1, "Die on checkbox." );
1542 test("live with submit", function() {
1543         expect(5);
1545         var count1 = 0, count2 = 0;
1547         jQuery("#testForm").live("submit", function(ev) {
1548                 count1++;
1549                 ev.preventDefault();
1550         });
1552         jQuery("body").live("submit", function(ev) {
1553                 count2++;
1554                 ev.preventDefault();
1555         });
1557         jQuery("#testForm input[name=sub1]").submit();
1558         equals( count1, 1, "Verify form submit." );
1559         equals( count2, 1, "Verify body submit." );
1561         jQuery("#testForm input[name=sub1]").live("click", function(ev) {
1562                 ok( true, "cancelling submit still calls click handler" );
1563         });
1565         jQuery("#testForm input[name=sub1]")[0].click();
1566         equals( count1, 2, "Verify form submit." );
1567         equals( count2, 2, "Verify body submit." );
1569         jQuery("#testForm").die("submit");
1570         jQuery("#testForm input[name=sub1]").die("click");
1571         jQuery("body").die("submit");
1574 test("live with special events", function() {
1575         expect(13);
1577         jQuery.event.special.foo = {
1578                 setup: function( data, namespaces, handler ) {
1579                         ok( true, "Setup run." );
1580                 },
1581                 teardown: function( namespaces ) {
1582                         ok( true, "Teardown run." );
1583                 },
1584                 add: function( handleObj ) {
1585                         ok( true, "Add run." );
1586                 },
1587                 remove: function( handleObj ) {
1588                         ok( true, "Remove run." );
1589                 },
1590                 _default: function( event ) {
1591                         ok( true, "Default run." );
1592                 }
1593         };
1595         // Run: setup, add
1596         jQuery("#liveSpan1").live("foo.a", function(e){
1597                 ok( true, "Handler 1 run." );
1598         });
1600         // Run: add
1601         jQuery("#liveSpan1").live("foo.b", function(e){
1602                 ok( true, "Handler 2 run." );
1603         });
1605         // Run: Handler 1, Handler 2, Default
1606         jQuery("#liveSpan1").trigger("foo");
1608         // Run: Handler 1, Default
1609         // TODO: Namespace doesn't trigger default (?)
1610         jQuery("#liveSpan1").trigger("foo.a");
1612         // Run: remove
1613         jQuery("#liveSpan1").die("foo.a");
1615         // Run: Handler 2, Default
1616         jQuery("#liveSpan1").trigger("foo");
1618         // Run: remove, teardown
1619         jQuery("#liveSpan1").die("foo");
1621         delete jQuery.event.special.foo;
1624 test(".delegate()/.undelegate()", function() {
1625         expect(65);
1627         var submit = 0, div = 0, livea = 0, liveb = 0;
1629         jQuery("#body").delegate("div", "submit", function(){ submit++; return false; });
1630         jQuery("#body").delegate("div", "click", function(){ div++; });
1631         jQuery("#body").delegate("div#nothiddendiv", "click", function(){ livea++; });
1632         jQuery("#body").delegate("div#nothiddendivchild", "click", function(){ liveb++; });
1634         // Nothing should trigger on the body
1635         jQuery("body").trigger("click");
1636         equals( submit, 0, "Click on body" );
1637         equals( div, 0, "Click on body" );
1638         equals( livea, 0, "Click on body" );
1639         equals( liveb, 0, "Click on body" );
1641         // This should trigger two events
1642         submit = 0, div = 0, livea = 0, liveb = 0;
1643         jQuery("div#nothiddendiv").trigger("click");
1644         equals( submit, 0, "Click on div" );
1645         equals( div, 1, "Click on div" );
1646         equals( livea, 1, "Click on div" );
1647         equals( liveb, 0, "Click on div" );
1649         // This should trigger three events (w/ bubbling)
1650         submit = 0, div = 0, livea = 0, liveb = 0;
1651         jQuery("div#nothiddendivchild").trigger("click");
1652         equals( submit, 0, "Click on inner div" );
1653         equals( div, 2, "Click on inner div" );
1654         equals( livea, 1, "Click on inner div" );
1655         equals( liveb, 1, "Click on inner div" );
1657         // This should trigger one submit
1658         submit = 0, div = 0, livea = 0, liveb = 0;
1659         jQuery("div#nothiddendivchild").trigger("submit");
1660         equals( submit, 1, "Submit on div" );
1661         equals( div, 0, "Submit on div" );
1662         equals( livea, 0, "Submit on div" );
1663         equals( liveb, 0, "Submit on div" );
1665         // Make sure no other events were removed in the process
1666         submit = 0, div = 0, livea = 0, liveb = 0;
1667         jQuery("div#nothiddendivchild").trigger("click");
1668         equals( submit, 0, "undelegate Click on inner div" );
1669         equals( div, 2, "undelegate Click on inner div" );
1670         equals( livea, 1, "undelegate Click on inner div" );
1671         equals( liveb, 1, "undelegate Click on inner div" );
1673         // Now make sure that the removal works
1674         submit = 0, div = 0, livea = 0, liveb = 0;
1675         jQuery("#body").undelegate("div#nothiddendivchild", "click");
1676         jQuery("div#nothiddendivchild").trigger("click");
1677         equals( submit, 0, "undelegate Click on inner div" );
1678         equals( div, 2, "undelegate Click on inner div" );
1679         equals( livea, 1, "undelegate Click on inner div" );
1680         equals( liveb, 0, "undelegate Click on inner div" );
1682         // Make sure that the click wasn't removed too early
1683         submit = 0, div = 0, livea = 0, liveb = 0;
1684         jQuery("div#nothiddendiv").trigger("click");
1685         equals( submit, 0, "undelegate Click on inner div" );
1686         equals( div, 1, "undelegate Click on inner div" );
1687         equals( livea, 1, "undelegate Click on inner div" );
1688         equals( liveb, 0, "undelegate Click on inner div" );
1690         // Make sure that stopPropgation doesn't stop live events
1691         submit = 0, div = 0, livea = 0, liveb = 0;
1692         jQuery("#body").delegate("div#nothiddendivchild", "click", function(e){ liveb++; e.stopPropagation(); });
1693         jQuery("div#nothiddendivchild").trigger("click");
1694         equals( submit, 0, "stopPropagation Click on inner div" );
1695         equals( div, 1, "stopPropagation Click on inner div" );
1696         equals( livea, 0, "stopPropagation Click on inner div" );
1697         equals( liveb, 1, "stopPropagation Click on inner div" );
1699         // Make sure click events only fire with primary click
1700         submit = 0, div = 0, livea = 0, liveb = 0;
1701         var event = jQuery.Event("click");
1702         event.button = 1;
1703         jQuery("div#nothiddendiv").trigger(event);
1705         equals( livea, 0, "delegate secondary click" );
1707         jQuery("#body").undelegate("div#nothiddendivchild", "click");
1708         jQuery("#body").undelegate("div#nothiddendiv", "click");
1709         jQuery("#body").undelegate("div", "click");
1710         jQuery("#body").undelegate("div", "submit");
1712         // Test binding with a different context
1713         var clicked = 0, container = jQuery("#main")[0];
1714         jQuery("#main").delegate("#foo", "click", function(e){ clicked++; });
1715         jQuery("div").trigger("click");
1716         jQuery("#foo").trigger("click");
1717         jQuery("#main").trigger("click");
1718         jQuery("body").trigger("click");
1719         equals( clicked, 2, "delegate with a context" );
1721         // Make sure the event is actually stored on the context
1722         ok( jQuery._data(container, "events").live, "delegate with a context" );
1724         // Test unbinding with a different context
1725         jQuery("#main").undelegate("#foo", "click");
1726         jQuery("#foo").trigger("click");
1727         equals( clicked, 2, "undelegate with a context");
1729         // Test binding with event data
1730         jQuery("#body").delegate("#foo", "click", true, function(e){ equals( e.data, true, "delegate with event data" ); });
1731         jQuery("#foo").trigger("click");
1732         jQuery("#body").undelegate("#foo", "click");
1734         // Test binding with trigger data
1735         jQuery("#body").delegate("#foo", "click", function(e, data){ equals( data, true, "delegate with trigger data" ); });
1736         jQuery("#foo").trigger("click", true);
1737         jQuery("#body").undelegate("#foo", "click");
1739         // Test binding with different this object
1740         jQuery("#body").delegate("#foo", "click", jQuery.proxy(function(e){ equals( this.foo, "bar", "delegate with event scope" ); }, { foo: "bar" }));
1741         jQuery("#foo").trigger("click");
1742         jQuery("#body").undelegate("#foo", "click");
1744         // Test binding with different this object, event data, and trigger data
1745         jQuery("#body").delegate("#foo", "click", true, jQuery.proxy(function(e, data){
1746                 equals( e.data, true, "delegate with with different this object, event data, and trigger data" );
1747                 equals( this.foo, "bar", "delegate with with different this object, event data, and trigger data" );
1748                 equals( data, true, "delegate with with different this object, event data, and trigger data")
1749         }, { foo: "bar" }));
1750         jQuery("#foo").trigger("click", true);
1751         jQuery("#body").undelegate("#foo", "click");
1753         // Verify that return false prevents default action
1754         jQuery("#body").delegate("#anchor2", "click", function(){ return false; });
1755         var hash = window.location.hash;
1756         jQuery("#anchor2").trigger("click");
1757         equals( window.location.hash, hash, "return false worked" );
1758         jQuery("#body").undelegate("#anchor2", "click");
1760         // Verify that .preventDefault() prevents default action
1761         jQuery("#body").delegate("#anchor2", "click", function(e){ e.preventDefault(); });
1762         var hash = window.location.hash;
1763         jQuery("#anchor2").trigger("click");
1764         equals( window.location.hash, hash, "e.preventDefault() worked" );
1765         jQuery("#body").undelegate("#anchor2", "click");
1767         // Test binding the same handler to multiple points
1768         var called = 0;
1769         function callback(){ called++; return false; }
1771         jQuery("#body").delegate("#nothiddendiv", "click", callback);
1772         jQuery("#body").delegate("#anchor2", "click", callback);
1774         jQuery("#nothiddendiv").trigger("click");
1775         equals( called, 1, "Verify that only one click occurred." );
1777         called = 0;
1778         jQuery("#anchor2").trigger("click");
1779         equals( called, 1, "Verify that only one click occurred." );
1781         // Make sure that only one callback is removed
1782         jQuery("#body").undelegate("#anchor2", "click", callback);
1784         called = 0;
1785         jQuery("#nothiddendiv").trigger("click");
1786         equals( called, 1, "Verify that only one click occurred." );
1788         called = 0;
1789         jQuery("#anchor2").trigger("click");
1790         equals( called, 0, "Verify that no click occurred." );
1792         // Make sure that it still works if the selector is the same,
1793         // but the event type is different
1794         jQuery("#body").delegate("#nothiddendiv", "foo", callback);
1796         // Cleanup
1797         jQuery("#body").undelegate("#nothiddendiv", "click", callback);
1799         called = 0;
1800         jQuery("#nothiddendiv").trigger("click");
1801         equals( called, 0, "Verify that no click occurred." );
1803         called = 0;
1804         jQuery("#nothiddendiv").trigger("foo");
1805         equals( called, 1, "Verify that one foo occurred." );
1807         // Cleanup
1808         jQuery("#body").undelegate("#nothiddendiv", "foo", callback);
1810         // Make sure we don't loose the target by DOM modifications
1811         // after the bubble already reached the liveHandler
1812         var livec = 0, elemDiv = jQuery("#nothiddendivchild").html("<span></span>").get(0);
1814         jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(""); });
1815         jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ if(e.target) {livec++;} });
1817         jQuery("#nothiddendiv span").click();
1818         equals( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." );
1819         equals( livec, 1, "Verify that second handler occurred even with nuked target." );
1821         // Cleanup
1822         jQuery("#body").undelegate("#nothiddendivchild", "click");
1824         // Verify that .live() ocurs and cancel buble in the same order as
1825         // we would expect .bind() and .click() without delegation
1826         var lived = 0, livee = 0;
1828         // bind one pair in one order
1829         jQuery("#body").delegate("span#liveSpan1 a", "click", function(){ lived++; return false; });
1830         jQuery("#body").delegate("span#liveSpan1", "click", function(){ livee++; });
1832         jQuery("span#liveSpan1 a").click();
1833         equals( lived, 1, "Verify that only one first handler occurred." );
1834         equals( livee, 0, "Verify that second handler doesn't." );
1836         // and one pair in inverse
1837         jQuery("#body").delegate("span#liveSpan2", "click", function(){ livee++; });
1838         jQuery("#body").delegate("span#liveSpan2 a", "click", function(){ lived++; return false; });
1840         lived = 0;
1841         livee = 0;
1842         jQuery("span#liveSpan2 a").click();
1843         equals( lived, 1, "Verify that only one first handler occurred." );
1844         equals( livee, 0, "Verify that second handler doesn't." );
1846         // Cleanup
1847         jQuery("#body").undelegate("click");
1849         // Test this, target and currentTarget are correct
1850         jQuery("#body").delegate("span#liveSpan1", "click", function(e){
1851                 equals( this.id, "liveSpan1", "Check the this within a delegate handler" );
1852                 equals( e.currentTarget.id, "liveSpan1", "Check the event.currentTarget within a delegate handler" );
1853                 equals( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a delegate handler" );
1854         });
1856         jQuery("span#liveSpan1 a").click();
1858         jQuery("#body").undelegate("span#liveSpan1", "click");
1860         // Work with deep selectors
1861         livee = 0;
1863         function clickB(){ livee++; }
1865         jQuery("#body").delegate("#nothiddendiv div", "click", function(){ livee++; });
1866         jQuery("#body").delegate("#nothiddendiv div", "click", clickB);
1867         jQuery("#body").delegate("#nothiddendiv div", "mouseover", function(){ livee++; });
1869         equals( livee, 0, "No clicks, deep selector." );
1871         livee = 0;
1872         jQuery("#nothiddendivchild").trigger("click");
1873         equals( livee, 2, "Click, deep selector." );
1875         livee = 0;
1876         jQuery("#nothiddendivchild").trigger("mouseover");
1877         equals( livee, 1, "Mouseover, deep selector." );
1879         jQuery("#body").undelegate("#nothiddendiv div", "mouseover");
1881         livee = 0;
1882         jQuery("#nothiddendivchild").trigger("click");
1883         equals( livee, 2, "Click, deep selector." );
1885         livee = 0;
1886         jQuery("#nothiddendivchild").trigger("mouseover");
1887         equals( livee, 0, "Mouseover, deep selector." );
1889         jQuery("#body").undelegate("#nothiddendiv div", "click", clickB);
1891         livee = 0;
1892         jQuery("#nothiddendivchild").trigger("click");
1893         equals( livee, 1, "Click, deep selector." );
1895         jQuery("#body").undelegate("#nothiddendiv div", "click");
1898 test("undelegate all bound events", function(){
1899         expect(1);
1901         var count = 0;
1902         var div = jQuery("#body");
1904         div.delegate("div#nothiddendivchild", "click submit", function(){ count++; });
1905         div.undelegate();
1907         jQuery("div#nothiddendivchild").trigger("click");
1908         jQuery("div#nothiddendivchild").trigger("submit");
1910         equals( count, 0, "Make sure no events were triggered." );
1913 test("delegate with multiple events", function(){
1914         expect(1);
1916         var count = 0;
1917         var div = jQuery("#body");
1919         div.delegate("div#nothiddendivchild", "click submit", function(){ count++; });
1921         jQuery("div#nothiddendivchild").trigger("click");
1922         jQuery("div#nothiddendivchild").trigger("submit");
1924         equals( count, 2, "Make sure both the click and submit were triggered." );
1926         jQuery("#body").undelegate();
1929 test("delegate with change", function(){
1930         expect(8);
1932         var selectChange = 0, checkboxChange = 0;
1934         var select = jQuery("select[name='S1']");
1935         jQuery("#body").delegate("select[name='S1']", "change", function() {
1936                 selectChange++;
1937         });
1939         var checkbox = jQuery("#check2"),
1940                 checkboxFunction = function(){
1941                         checkboxChange++;
1942                 }
1943         jQuery("#body").delegate("#check2", "change", checkboxFunction);
1945         // test click on select
1947         // second click that changed it
1948         selectChange = 0;
1949         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1950         select.trigger("change");
1951         equals( selectChange, 1, "Change on click." );
1953         // test keys on select
1954         selectChange = 0;
1955         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1956         select.trigger("change");
1957         equals( selectChange, 1, "Change on keyup." );
1959         // test click on checkbox
1960         checkbox.trigger("change");
1961         equals( checkboxChange, 1, "Change on checkbox." );
1963         // test blur/focus on text
1964         var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
1965         jQuery("#body").delegate("#name", "change", function() {
1966                 textChange++;
1967         });
1969         text.val(oldTextVal+"foo");
1970         text.trigger("change");
1971         equals( textChange, 1, "Change on text input." );
1973         text.val(oldTextVal);
1974         jQuery("#body").die("change");
1976         // test blur/focus on password
1977         var password = jQuery("#name"), passwordChange = 0, oldPasswordVal = password.val();
1978         jQuery("#body").delegate("#name", "change", function() {
1979                 passwordChange++;
1980         });
1982         password.val(oldPasswordVal + "foo");
1983         password.trigger("change");
1984         equals( passwordChange, 1, "Change on password input." );
1986         password.val(oldPasswordVal);
1987         jQuery("#body").undelegate("#name", "change");
1989         // make sure die works
1991         // die all changes
1992         selectChange = 0;
1993         jQuery("#body").undelegate("select[name='S1']", "change");
1994         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
1995         select.trigger("change");
1996         equals( selectChange, 0, "Die on click works." );
1998         selectChange = 0;
1999         select[0].selectedIndex = select[0].selectedIndex ? 0 : 1;
2000         select.trigger("change");
2001         equals( selectChange, 0, "Die on keyup works." );
2003         // die specific checkbox
2004         jQuery("#body").undelegate("#check2", "change", checkboxFunction);
2005         checkbox.trigger("change");
2006         equals( checkboxChange, 1, "Die on checkbox." );
2009 test("delegate with submit", function() {
2010         var count1 = 0, count2 = 0;
2012         jQuery("#body").delegate("#testForm", "submit", function(ev) {
2013                 count1++;
2014                 ev.preventDefault();
2015         });
2017         jQuery(document).delegate("body", "submit", function(ev) {
2018                 count2++;
2019                 ev.preventDefault();
2020         });
2022         jQuery("#testForm input[name=sub1]").submit();
2023         equals( count1, 1, "Verify form submit." );
2024         equals( count2, 1, "Verify body submit." );
2026         jQuery("#body").undelegate();
2027         jQuery(document).undelegate();
2030 test("undelegate() with only namespaces", function(){
2031         expect(2);
2033         var $delegate = jQuery("#liveHandlerOrder"),
2034                         count = 0;
2036         $delegate.delegate("a", "click.ns", function(e) {
2037                 count++;
2038         });
2040         jQuery("a", $delegate).eq(0).trigger("click.ns");
2042         equals( count, 1, "delegated click.ns");
2044         $delegate.undelegate(".ns");
2046         jQuery("a", $delegate).eq(1).trigger("click.ns");
2048         equals( count, 1, "no more .ns after undelegate");
2051 test("Non DOM element events", function() {
2052         expect(1);
2054         var o = {};
2056         jQuery(o).bind("nonelementobj", function(e) {
2057                 ok( true, "Event on non-DOM object triggered" );
2058         });
2060         jQuery(o).trigger("nonelementobj");
2063 test("window resize", function() {
2064         expect(2);
2066         jQuery(window).unbind();
2068         jQuery(window).bind("resize", function(){
2069                 ok( true, "Resize event fired." );
2070         }).resize().unbind("resize");
2072         ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." );
2075 test("focusin bubbles", function() {
2076         expect(5);
2078         var input = jQuery( "<input type='text' />" ).prependTo( "body" ),
2079                 order = 0;
2081         jQuery( "body" ).bind( "focusin.focusinBubblesTest", function(){
2082                 equals( 1, order++, "focusin on the body second" );
2083         });
2085         input.bind( "focusin.focusinBubblesTest", function(){
2086                 equals( 0, order++, "focusin on the element first" );
2087         });
2089         // DOM focus method
2090         input[0].focus();
2092         // To make the next focus test work, we need to take focus off the input.
2093         // This will fire another focusin event, so set order to reflect that.
2094         order = 1;
2095         jQuery("#text1")[0].focus();
2097         // jQuery trigger, which calls DOM focus
2098         order = 0;
2099         input.trigger( "focus" );
2101         input.remove();
2102         jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
2105 test("custom events with colons (#3533, #8272)", function() {
2106         expect(1);
2108         var tab = jQuery("<table><tr><td>trigger</td></tr></table>").appendTo("body");
2109         try {
2110                 tab.trigger("back:forth");
2111                 ok( true, "colon events don't throw" );
2112         } catch ( e ) {
2113                 ok( false, "colon events die" );
2114         };
2115         tab.remove();
2119 (function(){
2120         // This code must be run before DOM ready!
2121         var notYetReady, noEarlyExecution,
2122                 order = [],
2123                 args = {};
2125         notYetReady = !jQuery.isReady;
2127         test("jQuery.isReady", function() {
2128                 expect(2);
2130                 equals(notYetReady, true, "jQuery.isReady should not be true before DOM ready");
2131                 equals(jQuery.isReady, true, "jQuery.isReady should be true once DOM is ready");
2132         });
2134         // Create an event handler.
2135         function makeHandler( testId ) {
2136                 // When returned function is executed, push testId onto `order` array
2137                 // to ensure execution order. Also, store event handler arg to ensure
2138                 // the correct arg is being passed into the event handler.
2139                 return function( arg ) {
2140                         order.push(testId);
2141                         args[testId] = arg;
2142                 };
2143         }
2145         // Bind to the ready event in every possible way.
2146         jQuery(makeHandler("a"));
2147         jQuery(document).ready(makeHandler("b"));
2148         jQuery(document).bind("ready.readytest", makeHandler("c"));
2150         // Do it twice, just to be sure.
2151         jQuery(makeHandler("d"));
2152         jQuery(document).ready(makeHandler("e"));
2153         jQuery(document).bind("ready.readytest", makeHandler("f"));
2155         noEarlyExecution = order.length == 0;
2157         // This assumes that QUnit tests are run on DOM ready!
2158         test("jQuery ready", function() {
2159                 expect(10);
2161                 ok(noEarlyExecution, "Handlers bound to DOM ready should not execute before DOM ready");
2163                 // Ensure execution order.
2164                 same(order, ["a", "b", "d", "e", "c", "f"], "Bound DOM ready handlers should execute in bind-order, but those bound with jQuery(document).bind( 'ready', fn ) will always execute last");
2166                 // Ensure handler argument is correct.
2167                 equals(args.a, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
2168                 equals(args.b, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
2169                 ok(args.c instanceof jQuery.Event, "Argument passed to fn in jQuery(document).bind( 'ready', fn ) should be an event object");
2171                 order = [];
2173                 // Now that the ready event has fired, again bind to the ready event
2174                 // in every possible way. These event handlers should execute immediately.
2175                 jQuery(makeHandler("g"));
2176                 equals(order.pop(), "g", "Event handler should execute immediately");
2177                 equals(args.g, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
2179                 jQuery(document).ready(makeHandler("h"));
2180                 equals(order.pop(), "h", "Event handler should execute immediately");
2181                 equals(args.h, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
2183                 jQuery(document).bind("ready.readytest", makeHandler("never"));
2184                 equals(order.length, 0, "Event handler should never execute since DOM ready has already passed");
2186                 // Cleanup.
2187                 jQuery(document).unbind("ready.readytest");
2188         });
2190 })();
2193 test("event properties", function() {
2194         stop();
2195         jQuery("#simon1").click(function(event) {
2196                 ok( event.timeStamp, "assert event.timeStamp is present" );
2197                 start();
2198         }).click();