Fixed #1854 by using wizzud's suggestion. The only real difference is the code is only called when there is more than a single selector. So there should be no speed decrease in the current working cases. Only additional functionality for cases that used to fail.

This commit is contained in:
David Serduke 2007-12-13 22:24:59 +00:00
parent 3e3b86c7a7
commit da33a981c6
5 changed files with 29 additions and 14 deletions

View File

@ -342,15 +342,14 @@ jQuery.fn = jQuery.prototype = {
}, },
not: function( selector ) { not: function( selector ) {
return this.pushStack( if (selector.constructor == String)
selector.constructor == String && // test special case where just one selector is passed in
jQuery.multiFilter( selector, this, true ) || if ( /^.[^:#\[\.]*$/.test(selector) )
return this.pushStack( jQuery.multiFilter( selector, this, true ) );
else
selector = jQuery.multiFilter( selector, this );
jQuery.grep(this, function(elem) { return this.pushStack( jQuery.removeFromArray( selector, this ) );
return selector.constructor == Array || selector.jquery ?
jQuery.inArray( elem, selector ) < 0 :
elem != selector;
}) );
}, },
add: function( selector ) { add: function( selector ) {
@ -1093,6 +1092,13 @@ jQuery.extend({
return -1; return -1;
}, },
removeFromArray: function( remove, from ) {
var isArrayLike = remove.length && remove[remove.length - 1] !== undefined;
return jQuery.grep(from, function(elem) {
return isArrayLike ? jQuery.inArray( elem, remove ) < 0 : elem != from;
});
},
merge: function( first, second ) { merge: function( first, second ) {
// We have to loop this way because IE & Opera overwrite the length // We have to loop this way because IE & Opera overwrite the length
// expando of getElementsByTagName // expando of getElementsByTagName

View File

@ -320,7 +320,11 @@ jQuery.extend({
// :not() is a special case that can be optimized by // :not() is a special case that can be optimized by
// keeping it out of the expression list // keeping it out of the expression list
if ( m[1] == ":" && m[2] == "not" ) if ( m[1] == ":" && m[2] == "not" )
// optimize if only one selector found (most common case)
if ( /^.[^:#\[\.]*$/.test(m[3]) )
r = jQuery.filter(m[3], r, true).r; r = jQuery.filter(m[3], r, true).r;
else
r = jQuery.removeFromArray(jQuery.multiFilter(m[3], r), r);
// We can get a big speed boost by filtering by class here // We can get a big speed boost by filtering by class here
else if ( m[1] == "." ) else if ( m[1] == "." )

View File

@ -61,19 +61,19 @@
<textarea id="area1" maxlength="30">foobar</textarea> <textarea id="area1" maxlength="30">foobar</textarea>
<select name="select1" id="select1"> <select name="select1" id="select1">
<option id="option1a" value="">Nothing</option> <option id="option1a" class="emptyopt" value="">Nothing</option>
<option id="option1b" value="1">1</option> <option id="option1b" value="1">1</option>
<option id="option1c" value="2">2</option> <option id="option1c" value="2">2</option>
<option id="option1d" value="3">3</option> <option id="option1d" value="3">3</option>
</select> </select>
<select name="select2" id="select2"> <select name="select2" id="select2">
<option id="option2a" value="">Nothing</option> <option id="option2a" class="emptyopt" value="">Nothing</option>
<option id="option2b" value="1">1</option> <option id="option2b" value="1">1</option>
<option id="option2c" value="2">2</option> <option id="option2c" value="2">2</option>
<option id="option2d" selected="selected" value="3">3</option> <option id="option2d" selected="selected" value="3">3</option>
</select> </select>
<select name="select3" id="select3" multiple="multiple"> <select name="select3" id="select3" multiple="multiple">
<option id="option3a" value="">Nothing</option> <option id="option3a" class="emptyopt" value="">Nothing</option>
<option id="option3b" selected="selected" value="1">1</option> <option id="option3b" selected="selected" value="1">1</option>
<option id="option3c" selected="selected" value="2">2</option> <option id="option3c" selected="selected" value="2">2</option>
<option id="option3d" value="3">3</option> <option id="option3d" value="3">3</option>

View File

@ -1052,10 +1052,12 @@ test("filter()", function() {
}); });
test("not()", function() { test("not()", function() {
expect(3); expect(5);
ok( $("#main > p#ap > a").not("#google").length == 2, "not('selector')" ); ok( $("#main > p#ap > a").not("#google").length == 2, "not('selector')" );
isSet( $("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" );
isSet( $("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); isSet( $("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );
isSet( $("p").not($("#ap, #sndp, .result")).get(), q("firstp", "en", "sap", "first"), "not(jQuery)" ); isSet( $("p").not($("#ap, #sndp, .result")).get(), q("firstp", "en", "sap", "first"), "not(jQuery)" );
isSet( $("#form option").not("option.emptyopt:contains('Nothing'),[selected],[value='1']").get(), q("option1c", "option1d", "option2c", "option3d" ), "not('complex selector')");
}); });
test("andSelf()", function() { test("andSelf()", function() {

View File

@ -182,7 +182,7 @@ test("attributes", function() {
}); });
test("pseudo (:) selectors", function() { test("pseudo (:) selectors", function() {
expect(32); expect(35);
t( "First Child", "p:first-child", ["firstp","sndp"] ); t( "First Child", "p:first-child", ["firstp","sndp"] );
t( "Last Child", "p:last-child", ["sap"] ); t( "Last Child", "p:last-child", ["sap"] );
t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] ); t( "Only Child", "a:only-child", ["simon1","anchor1","yahoo","anchor2"] );
@ -195,6 +195,9 @@ test("pseudo (:) selectors", function() {
t( "Text Contains", "a:contains('Google Groups')", ["groups"] ); t( "Text Contains", "a:contains('Google Groups')", ["groups"] );
t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests"] ); t( "Element Preceded By", "p ~ div", ["foo","fx-queue","fx-tests", "moretests"] );
t( "Not", "a.blog:not(.link)", ["mark"] ); t( "Not", "a.blog:not(.link)", ["mark"] );
t( "Not - multiple", "#form option:not(:contains('Nothing'),#option1b,:selected)", ["option1c", "option1d", "option2b", "option2c", "option3d"] );
t( "Not - complex", "#form option:not([id^='opt']:gt(0):nth-child(-n+3))", [ "option1a", "option1d", "option2d", "option3d"] );
t( "Not - recursive", "#form option:not(:not(:selected))[id^='option3']", [ "option3b", "option3c"] );
t( "nth Element", "p:nth(1)", ["ap"] ); t( "nth Element", "p:nth(1)", ["ap"] );
t( "First Element", "p:first", ["firstp"] ); t( "First Element", "p:first", ["firstp"] );