diff --git a/src/event.js b/src/event.js index 873a6ddcb..cc85ec56a 100644 --- a/src/event.js +++ b/src/event.js @@ -7,7 +7,7 @@ var rnamespaces = /\.(.*)$/, rescape = /[^\w\s.|`]/g, rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/, rhoverHack = /\bhover(\.\S+)?/, - rquickIs = /^([\w\-]+)?(?:#([\w\-]+))?(?:\.([\w\-]+))?(?:\[([\w+\-]+)=["']?([\w\-]*)["']?\])(:first-child|:last-child|:empty)?$/, + rquickIs = /^([\w\-]+)?(?:#([\w\-]+))?(?:\.([\w\-]+))?(?:\[([\w+\-]+)=["']?([\w\-]*)["']?\])?(:first-child|:last-child|:empty)?$/, delegateTypeMap = { focus: "focusin", blur: "focusout", @@ -69,12 +69,12 @@ jQuery.event = { // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); - types = types.replace( rhoverHack, "mouseover$1 mouseout$1" ).split(" "); + types = types.replace( rhoverHack, "mouseover$1 mouseout$1" ).split( " " ); for ( t = 0; t < types.length; t++ ) { tns = rtypenamespace.exec( types[t] ) || []; type = tns[1]; - namespaces = (tns[2] || "").split(".").sort(); + namespaces = (tns[2] || "").split( "." ).sort(); handleObj = jQuery.extend({ type: type, data: data, @@ -112,7 +112,7 @@ jQuery.event = { } // Pre-analyze selector so we can process it quickly on event dispatch - quick = handleObj.quick = rquickIs.exec(selector); + quick = handleObj.quick = rquickIs.exec( selector ); if ( quick ) { // 0 1 2 3 4 5 6 // [ _, tag, id, class, attrName, attrValue, pseudo(:empty :first-child :last-child) ] diff --git a/test/unit/event.js b/test/unit/event.js index db6013e4e..235ab4bcb 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2306,12 +2306,44 @@ test(".on and .off", function() { }); test("delegated events quickIs", function() { - expect(1); - ok( false, "write a unit test you lazy slob!" ); -//TODO: specific unit tests for quickIs selector cases -//TODO: make a test to ensure == matches the null returned by getAttribute for [name] -//ALSO: will quick[5] return undefined in all regexp impls? If not fix it + expect(23); + var markup = jQuery( '

deadbeatclub

workedorborked?' ), + str, + check = function(el, expect){ + str = ""; + markup.find( el ).trigger( "blink" ); + equals( str, expect, "On " + el ); + }, + func = function(e){ + var tag = this.nodeName.toLowerCase(); + str += (str && " ") + tag + "|" + e.handleObj.selector; + ok( e.handleObj.quick, "Selector "+ e.handleObj.selector + " on " + tag + " is a quickIs case" ); + }; + // tag#id.class[name=value] + markup + .appendTo( "body " ) + .on( "blink", "em", func ) + .on( "blink", ".D", func ) + .on( "blink", ".d", func ) + .on( "blink", "p.d", func ) + .on( "blink", "[devo=cool]", func ) + .on( "blink", "[devo='NO']", func ) + .on( "blink", "#famous", func ) + .on( "blink", "em:empty", func ) + .on( "blink", ":first-child", func ) + .on( "blink", "em:last-child", func ); + + check( "[devo=cool]", "b|[devo=cool] p|.D p|:first-child" ); + check( "[devo='']", "" ); + check( "p", "p|.D p|:first-child" ); + check( "b", "b|[devo=cool] p|.D p|:first-child" ); + check( "em", "em|em quote|#famous em|em em|em:empty em|em:last-child quote|#famous" ); + + markup.find( "b" ).attr( "devo", "NO" ); + check( "b", "b|[devo='NO'] p|.D p|:first-child" ); + + markup.remove(); });