diff --git a/src/core.js b/src/core.js index 53d5f4a4..30820bf9 100644 --- a/src/core.js +++ b/src/core.js @@ -342,15 +342,14 @@ jQuery.fn = jQuery.prototype = { }, not: function( selector ) { - return this.pushStack( - selector.constructor == String && - jQuery.multiFilter( selector, this, true ) || + if (selector.constructor == String) + // test special case where just one selector is passed in + if ( /^.[^:#\[\.]*$/.test(selector) ) + return this.pushStack( jQuery.multiFilter( selector, this, true ) ); + else + selector = jQuery.multiFilter( selector, this ); - jQuery.grep(this, function(elem) { - return selector.constructor == Array || selector.jquery ? - jQuery.inArray( elem, selector ) < 0 : - elem != selector; - }) ); + return this.pushStack( jQuery.removeFromArray( selector, this ) ); }, add: function( selector ) { @@ -1093,6 +1092,13 @@ jQuery.extend({ 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 ) { // We have to loop this way because IE & Opera overwrite the length // expando of getElementsByTagName diff --git a/src/selector.js b/src/selector.js index c35fbb1e..6e916a2e 100644 --- a/src/selector.js +++ b/src/selector.js @@ -320,7 +320,11 @@ jQuery.extend({ // :not() is a special case that can be optimized by // keeping it out of the expression list if ( m[1] == ":" && m[2] == "not" ) - r = jQuery.filter(m[3], r, true).r; + // optimize if only one selector found (most common case) + if ( /^.[^:#\[\.]*$/.test(m[3]) ) + 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 else if ( m[1] == "." ) diff --git a/test/index.html b/test/index.html index cdd6a30b..b062179f 100644 --- a/test/index.html +++ b/test/index.html @@ -61,19 +61,19 @@