diff --git a/src/event.js b/src/event.js index ac0da6b7e8..1d92362799 100644 --- a/src/event.js +++ b/src/event.js @@ -304,7 +304,7 @@ jQuery.event = { } event.namespace = namespaces.join("."); event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); - + // Handle a global trigger if ( !elem ) { // Don't bubble custom events when global (to avoid too much overhead) @@ -574,6 +574,9 @@ jQuery.Event = function( src ) { } } + // Always ensure a type has been explicitly set + this.type = src.type; + // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || @@ -1030,10 +1033,18 @@ jQuery.each(["live", "die"], function( i, name ) { return this; } + if ( name === "die" && !types && + origSelector && origSelector[0] === "." ) { + + context.unbind( origSelector ); + + return this; + } + if ( data === false || jQuery.isFunction( data ) ) { fn = data || returnFalse; data = undefined; - } + } types = (types || "").split(" "); diff --git a/src/traversing.js b/src/traversing.js index fb5946bba8..e0f40151da 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -73,9 +73,9 @@ jQuery.fn.extend({ }, is: function( selector ) { - return !!selector && (typeof selector === "string" ? + return !!selector && ( typeof selector === "string" ? jQuery.filter( selector, this ).length > 0 : - this.filter( selector ).length > 0); + this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { @@ -298,13 +298,18 @@ jQuery.extend({ // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); - } else if ( qualifier && qualifier.nodeType ) { + } else if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem, i ) { return (elem === qualifier) === keep; }); diff --git a/test/unit/event.js b/test/unit/event.js index cefdf58337..b1fd919f58 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2022,6 +2022,27 @@ test("delegate with submit", function() { jQuery(document).undelegate(); }); +test("undelegate() with only namespaces", function(){ + expect(2); + + var $delegate = jQuery("#liveHandlerOrder"), + count = 0; + + $delegate.delegate("a", "click.ns", function(e) { + count++; + }); + + jQuery("a", $delegate).eq(0).trigger("click.ns"); + + equals( count, 1, "delegated click.ns"); + + $delegate.undelegate(".ns"); + + jQuery("a", $delegate).eq(1).trigger("click.ns"); + + equals( count, 1, "no more .ns after undelegate"); +}); + test("Non DOM element events", function() { expect(1); diff --git a/test/unit/traversing.js b/test/unit/traversing.js index 6228a0b98f..140b337aa8 100644 --- a/test/unit/traversing.js +++ b/test/unit/traversing.js @@ -72,7 +72,7 @@ test("is(String|undefined)", function() { }); test("is(jQuery)", function() { - expect(24); + expect(23); ok( jQuery('#form').is( jQuery('form') ), 'Check for element: A form is a form' ); ok( !jQuery('#form').is( jQuery('div') ), 'Check for element: A form is not a div' ); ok( jQuery('#mark').is( jQuery('.blog') ), 'Check for class: Expected class "blog"' ); @@ -83,7 +83,6 @@ test("is(jQuery)", function() { ok( !jQuery('#en').is( jQuery('[lang="de"]') ), 'Check for attribute: Expected attribute lang to be "en", not "de"' ); ok( jQuery('#text1').is( jQuery('[type="text"]') ), 'Check for attribute: Expected attribute type to be "text"' ); ok( !jQuery('#text1').is( jQuery('[type="radio"]') ), 'Check for attribute: Expected attribute type to be "text", not "radio"' ); - ok( jQuery('#text2').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected to be disabled' ); ok( !jQuery('#text1').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected not disabled' ); ok( jQuery('#radio2').is( jQuery(':checked') ), 'Check for pseudoclass: Expected to be checked' ); ok( !jQuery('#radio1').is( jQuery(':checked') ), 'Check for pseudoclass: Expected not checked' ); @@ -223,10 +222,6 @@ test("closest(Array)", function() { same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" ); }); -<<<<<<< HEAD -test("not(Selector|undefined)", function() { - expect(11); -======= test("closest(jQuery)", function() { expect(8); var $child = jQuery("#nothiddendivchild"), @@ -243,9 +238,8 @@ test("closest(jQuery)", function() { ok( $child.closest( $body.add($parent) ).is('#nothiddendiv'), "Closest ancestor retrieved." ); }); -test("not(Selector)", function() { - expect(7); ->>>>>>> 1a167767305202797cf4c839eb64bd7adfb00182 +test("not(Selector|undefined)", function() { + expect(11); equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" ); same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );