Changeset 5990
- Timestamp:
- 12/22/08 04:59:34 (6 months ago)
- Location:
- trunk/jquery
- Files:
-
- 2 modified
-
src/event.js (modified) (9 diffs)
-
test/unit/event.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/jquery/src/event.js
r5988 r5990 54 54 jQuery.each(types.split(/\s+/), function(index, type) { 55 55 // Namespaced event handlers 56 var parts = type.split(".");57 type = parts.shift();58 handler.type = parts.sort().join(".");56 var namespaces = type.split("."); 57 type = namespaces.shift(); 58 handler.type = namespaces.slice().sort().join("."); 59 59 60 60 // Get the current list of functions bound to this event 61 61 var handlers = events[type]; 62 63 if ( jQuery.event.specialAll[type] ) 64 jQuery.event.specialAll[type].setup.call(elem, data, namespaces); 62 65 63 66 // Init the event handler queue … … 68 71 // Only use addEventListener/attachEvent if the special 69 72 // events handler returns false 70 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data) === false ) {73 if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem, data, namespaces) === false ) { 71 74 // Bind the global event handler to the element 72 75 if (elem.addEventListener) … … 115 118 jQuery.each(types.split(/\s+/), function(index, type){ 116 119 // Namespaced event handlers 117 var namespace = type.split(".");118 type = namespace .shift();119 namespace = RegExp("(^|\\.)" + namespace.sort().join(".*\\.") + "(\\.|$)");120 var namespaces = type.split("."); 121 type = namespaces.shift(); 122 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); 120 123 121 124 if ( events[type] ) { … … 130 133 if ( namespace.test(events[type][handler].type) ) 131 134 delete events[type][handler]; 135 136 if ( jQuery.event.specialAll[type] ) 137 jQuery.event.specialAll[type].teardown.call(elem, namespaces); 132 138 133 139 // remove generic event handler if no more handlers exist 134 140 for ( ret in events[type] ) break; 135 141 if ( !ret ) { 136 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem ) === false ) {142 if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem, namespaces) === false ) { 137 143 if (elem.removeEventListener) 138 144 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); … … 158 164 }, 159 165 160 trigger: function(type, data, elem, donative, extra ) {166 trigger: function(type, data, elem, donative, extra, dohandlers) { 161 167 // Clone the incoming data, if any 162 168 data = jQuery.makeArray(data); … … 204 210 data[0].exclusive = true; 205 211 206 // Trigger the event, it is assumed that "handle" is a function 207 var handle = jQuery.data(elem, "handle"); 208 if ( handle ) 209 val = handle.apply( elem, data ); 210 211 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 212 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 213 val = false; 212 if ( dohandlers !== false ) { 213 // Trigger the event, it is assumed that "handle" is a function 214 var handle = jQuery.data(elem, "handle"); 215 if ( handle ) 216 val = handle.apply( elem, data ); 217 218 // Handle triggering native .onfoo handlers (and on links since we don't call .click() for links) 219 if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false ) 220 val = false; 221 } 214 222 215 223 if ( donative !== false && val !== false ) { … … 249 257 handle: function(event) { 250 258 // returned undefined or false 251 var val, ret, namespace,all, handlers;259 var val, ret, all, handlers; 252 260 253 261 event = arguments[0] = jQuery.event.fix( event || window.event ); 254 262 255 263 // Namespaced event handlers 256 namespace= event.type.split(".");257 event.type = namespace .shift();264 var namespaces = event.type.split("."); 265 event.type = namespaces.shift(); 258 266 259 267 // Cache this now, all = true means, any handler 260 all = !namespace .length && !event.exclusive;268 all = !namespaces.length && !event.exclusive; 261 269 262 namespace = RegExp("(^|\\.)" + namespace.sort().join(".*\\.") + "(\\.|$)");270 var namespace = RegExp("(^|\\.)" + namespaces.slice().sort().join(".*\\.") + "(\\.|$)"); 263 271 264 272 handlers = ( jQuery.data(this, "events") || {} )[event.type]; … … 381 389 setup: bindReady, 382 390 teardown: function() {} 391 } 392 }, 393 394 specialAll: { 395 live: { 396 setup: function( selector, namespaces ){ 397 jQuery.event.add( this, namespaces[0], liveHandler ); 398 }, 399 teardown: function( namespaces ){ 400 if ( namespaces.length ) { 401 var remove = 0, name = RegExp("(^|\\.)" + namespaces[0] + "(\\.|$)"); 402 403 jQuery.each( (jQuery.data(this, "events").live || {}), function(){ 404 if ( name.test(this.type) ) 405 remove++; 406 }); 407 408 if ( remove <= 1 ) 409 jQuery.event.remove( this, namespaces[0], liveHandler ); 410 } 411 } 383 412 } 384 413 } … … 494 523 495 524 return this; 525 }, 526 527 live: function( type, fn ){ 528 jQuery(document).bind( liveConvert(type, this.selector), this.selector, fn ); 529 return this; 530 }, 531 532 die: function( type, fn ){ 533 jQuery(document).unbind( liveConvert(type, this.selector), fn ); 534 return this; 496 535 } 497 536 }); 537 538 function liveHandler( event ){ 539 var check = RegExp("(^|\\.)" + event.type + "(\\.|$)"); 540 jQuery.each(jQuery.data(this, "events").live || [], function(i, fn){ 541 if ( check.test(fn.type) ) { 542 var elem = jQuery(event.target).closest(fn.data)[0]; 543 if ( elem ) 544 jQuery.event.trigger( event.type, fn.data, elem, false, fn, false ); 545 } 546 }); 547 } 548 549 function liveConvert(type, selector){ 550 return ["live", type, selector.replace(/\./g, "_")].join("."); 551 } 498 552 499 553 jQuery.extend({ -
trunk/jquery/test/unit/event.js
r5989 r5990 419 419 ok( !data, "Unbinding one function from toggle unbinds them all"); 420 420 }); 421 422 test(".live()/.die()", function() { 423 expect(28); 424 425 var submit = 0, div = 0, livea = 0, liveb = 0; 426 427 jQuery("div").live("submit", function(){ submit++; return false; }); 428 jQuery("div").live("click", function(){ div++; }); 429 jQuery("div#nothiddendiv").live("click", function(){ livea++; }); 430 jQuery("div#nothiddendivchild").live("click", function(){ liveb++; }); 431 432 // Nothing should trigger on the body 433 jQuery("body").trigger("click"); 434 equals( submit, 0, "Click on body" ); 435 equals( div, 0, "Click on body" ); 436 equals( livea, 0, "Click on body" ); 437 equals( liveb, 0, "Click on body" ); 438 439 // This should trigger two events 440 jQuery("div#nothiddendiv").trigger("click"); 441 equals( submit, 0, "Click on div" ); 442 equals( div, 1, "Click on div" ); 443 equals( livea, 1, "Click on div" ); 444 equals( liveb, 0, "Click on div" ); 445 446 // This should trigger three events (w/ bubbling) 447 jQuery("div#nothiddendivchild").trigger("click"); 448 equals( submit, 0, "Click on inner div" ); 449 equals( div, 2, "Click on inner div" ); 450 equals( livea, 2, "Click on inner div" ); 451 equals( liveb, 1, "Click on inner div" ); 452 453 // This should trigger one submit 454 jQuery("div#nothiddendivchild").trigger("submit"); 455 equals( submit, 1, "Submit on div" ); 456 equals( div, 2, "Submit on div" ); 457 equals( livea, 2, "Submit on div" ); 458 equals( liveb, 1, "Submit on div" ); 459 460 // Make sure no other events were removed in the process 461 jQuery("div#nothiddendivchild").trigger("click"); 462 equals( submit, 1, "die Click on inner div" ); 463 equals( div, 3, "die Click on inner div" ); 464 equals( livea, 3, "die Click on inner div" ); 465 equals( liveb, 2, "die Click on inner div" ); 466 467 // Now make sure that the removal works 468 jQuery("div#nothiddendivchild").die("click"); 469 jQuery("div#nothiddendivchild").trigger("click"); 470 equals( submit, 1, "die Click on inner div" ); 471 equals( div, 4, "die Click on inner div" ); 472 equals( livea, 4, "die Click on inner div" ); 473 equals( liveb, 2, "die Click on inner div" ); 474 475 // Make sure that the click wasn't removed too early 476 jQuery("div#nothiddendiv").trigger("click"); 477 equals( submit, 1, "die Click on inner div" ); 478 equals( div, 5, "die Click on inner div" ); 479 equals( livea, 5, "die Click on inner div" ); 480 equals( liveb, 2, "die Click on inner div" ); 481 482 jQuery("div#nothiddendiv").die("click"); 483 jQuery("div").die("click"); 484 jQuery("div").die("submit"); 485 }); 486 421 487 /* 422 488 test("jQuery(function($) {})", function() {
