From 713cc8609637a943f77039726d96f5e9f7a36f2b Mon Sep 17 00:00:00 2001 From: timmywil Date: Mon, 18 Jun 2012 18:43:50 -0400 Subject: [PATCH] Move quickIs to Sizzle; Remove duplicate id matching in init; Added selector caching to Sizzle. Fixes #11826. --- src/core.js | 66 ++++++++++++++-------------------------------- src/event.js | 26 ++---------------- src/sizzle | 2 +- test/unit/event.js | 44 ------------------------------- 4 files changed, 23 insertions(+), 115 deletions(-) diff --git a/src/core.js b/src/core.js index f4b760aee..c0113a190 100644 --- a/src/core.js +++ b/src/core.js @@ -39,9 +39,9 @@ var trimLeft = /^\s+/, trimRight = /\s+$/, - // A simple way to check for HTML strings or ID strings + // A simple way to check for HTML strings // Prioritize #id over to avoid XSS via location.hash (#9521) - quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + rhtmlString = /^(?:[^#<]*(<[\w\W]+>)[^>]*$)/, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, @@ -90,8 +90,8 @@ jQuery.fn = jQuery.prototype = { init: function( selector, context, rootjQuery ) { var match, elem, ret, doc; - // Handle $(""), $(null), or $(undefined) - if ( !selector ) { + // Handle $(""), $(null), $(undefined), $(false), or $("#") for location.hash + if ( !selector || selector === "#" ) { return this; } @@ -110,57 +110,31 @@ jQuery.fn = jQuery.prototype = { match = [ null, selector, null ]; } else { - match = quickExpr.exec( selector ); + match = rhtmlString.exec( selector ); } - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { + // HANDLE: $(html) -> $(array) + if ( match && match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + // If a single string is passed in and it's a single tag + // just do a createElement and skip the rest + ret = rsingleTag.exec( selector ); - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - ret = rsingleTag.exec( selector ); - - if ( ret ) { - selector = [ doc.createElement( ret[1] ) ]; - if ( jQuery.isPlainObject( context ) ) { - this.attr.call( selector, context, true ); - } - - } else { - ret = jQuery.buildFragment( [ match[1] ], doc ); - selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; + if ( ret ) { + selector = [ doc.createElement( ret[1] ) ]; + if ( jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); } - return jQuery.merge( this, selector ); - - // HANDLE: $("#id") } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; + ret = jQuery.buildFragment( [ match[1] ], doc ); + selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes; } + return jQuery.merge( this, selector ); + // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || rootjQuery ).find( selector ); diff --git a/src/event.js b/src/event.js index bc08e4782..6f7252489 100644 --- a/src/event.js +++ b/src/event.js @@ -4,25 +4,6 @@ var rformElems = /^(?:textarea|input|select)$/i, rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|contextmenu)|click/, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/, - quickParse = function( selector ) { - var quick = rquickIs.exec( selector ); - if ( quick ) { - // 0 1 2 3 - // [ _, tag, id, class ] - quick[1] = ( quick[1] || "" ).toLowerCase(); - quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" ); - } - return quick; - }, - quickIs = function( elem, m ) { - var attrs = elem.attributes || {}; - return ( - (!m[1] || elem.nodeName.toLowerCase() === m[1]) && - (!m[2] || (attrs.id || {}).value === m[2]) && - (!m[3] || m[3].test( (attrs[ "class" ] || {}).value )) - ); - }, hoverHack = function( events ) { return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); }; @@ -37,7 +18,7 @@ jQuery.event = { var elemData, eventHandle, events, t, tns, type, namespaces, handleObj, - handleObjIn, quick, handlers, special; + handleObjIn, handlers, special; // Don't attach events to noData or text/comment nodes (allow plain objects tho) if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { @@ -100,7 +81,6 @@ jQuery.event = { handler: handler, guid: handler.guid, selector: selector, - quick: selector && quickParse( selector ), namespace: namespaces.join(".") }, handleObjIn ); @@ -418,9 +398,7 @@ jQuery.event = { sel = handleObj.selector; if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = ( - handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel ) - ); + selMatch[ sel ] = jqcur.is( sel ); } if ( selMatch[ sel ] ) { matches.push( handleObj ); diff --git a/src/sizzle b/src/sizzle index 8881bb2d2..d2a68c583 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 8881bb2d21a017e4918e4ff81ee2fe716420d2b2 +Subproject commit d2a68c5835d648a00bce62d41a7e4cf43b1c17bc diff --git a/test/unit/event.js b/test/unit/event.js index 36cb53aec..ddbb5634e 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2793,50 +2793,6 @@ test("clone() delegated events (#11076)", function() { clone.remove(); }); -test("delegated events quickIs", function() { - expect(14); - var markup = jQuery( - '
'+ - '

'+ - 'deadbeatclub'+ - '

'+ - ''+ - 'workedorborked?'+ - ''+ - '
' - ), - str, - check = function(el, expect){ - str = ""; - markup.find( el ).trigger( "blink" ); - equal( 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", ".devo-like", func ) - .on( "blink", ".devo", func ) - .on( "blink", ".d", func ) - .on( "blink", "p.d", func ) - .on( "blink", "#famous", func ); - - check( ".devo-like", "b|.devo-like p|.D" ); - check( ".devo", "" ); - check( "p", "p|.D" ); - check( "b", "b|.devo-like p|.D" ); - check( "em", "em|em q|#famous em|em q|#famous" ); - - markup.remove(); -}); - test("fixHooks extensions", function() { expect( 2 ); -- 2.39.5