From f2ff0db0320cfab0d856ff68d012cb843c97b600 Mon Sep 17 00:00:00 2001 From: John Resig Date: Wed, 10 Jan 2007 17:54:42 +0000 Subject: [PATCH] Lots of improvements. Added support for .not( jQuery("...") ) and support for multi filters: .filter("foo,bar") .parent("div, .class"), etc. --- src/jquery/coreTest.js | 7 ++--- src/jquery/jquery.js | 62 ++++++++++++++++++++++++++-------------- src/selector/selector.js | 18 ++++++++++++ 3 files changed, 61 insertions(+), 26 deletions(-) diff --git a/src/jquery/coreTest.js b/src/jquery/coreTest.js index d8328c9c0..ccd84f72b 100644 --- a/src/jquery/coreTest.js +++ b/src/jquery/coreTest.js @@ -472,9 +472,8 @@ test("html(String)", function() { }); test("filter()", function() { - expect(5); + expect(4); isSet( $("input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" ); - isSet( $("p").filter(["#ap", "#sndp"]).get(), q("ap", "sndp"), "filter(Array<String>)" ); isSet( $("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" ); isSet( $("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" ); isSet( $("p").filter(function() { return !$("a", this).length }).get(), q("sndp", "first"), "filter(Function)" ); @@ -483,7 +482,7 @@ test("filter()", function() { test("not(String)", function() { expect(2); ok( $("#main > p#ap > a").not("#google").length == 2, "not('selector')" ); - isSet( $("p").not("#ap, #sndp").get(), q("firstp", "en", "sap", "first", "result"), "not('selector, selector')" ); + isSet( $("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); }); @@ -647,4 +646,4 @@ test("eq(), gt(), lt(), contains()", function() { isSet( $("#ap a").gt(0).get(), q("groups", "anchor1", "mark"), "gt()" ); isSet( $("#ap a").lt(3).get(), q("google", "groups", "anchor1"), "lt()" ); isSet( $("#foo a").contains("log").get(), q("anchor2", "simon"), "contains()" ); -}); \ No newline at end of file +}); diff --git a/src/jquery/jquery.js b/src/jquery/jquery.js index 401fd142d..cc0af5212 100644 --- a/src/jquery/jquery.js +++ b/src/jquery/jquery.js @@ -812,21 +812,21 @@ jQuery.fn = jQuery.prototype = { * match the specified expression(s). This method is used to narrow down * the results of a search. * - * Provide a String array of expressions to apply multiple filters at once. + * Provide a comma-separated list of expressions to apply multiple filters at once. * * @example $("p").filter(".selected") * @before

Hello

How are you?

* @result [

Hello

] * @desc Selects all paragraphs and removes those without a class "selected". * - * @example $("p").filter([".selected", ":first"]) + * @example $("p").filter(".selected, :first") * @before

Hello

Hello Again

And Again

* @result [

Hello

,

And Again

] * @desc Selects all paragraphs and removes those without class "selected" and being the first one. * * @name filter * @type jQuery - * @param String|Array expression Expression(s) to search with. + * @param String expression Expression(s) to search with. * @cat DOM/Traversing */ @@ -849,21 +849,12 @@ jQuery.fn = jQuery.prototype = { */ filter: function(t) { return this.pushStack( - t.constructor == Array && - jQuery.map(this,function(a){ - for ( var i = 0, tl = t.length; i < tl; i++ ) - if ( jQuery.filter(t[i],[a]).r.length ) - return a; - return null; + t.constructor == Function && + jQuery.grep(this, function(el, index){ + return t.apply(el, [index]) }) || - t.constructor == Boolean && - ( t ? this.get() : [] ) || - - typeof t == "function" && - jQuery.grep( this, function(el, index) { return t.apply(el, [index]) }) || - - jQuery.filter(t,this).r ); + jQuery.multiFilter(t,this) ); }, /** @@ -896,10 +887,33 @@ jQuery.fn = jQuery.prototype = { * @param String expr An expression with which to remove matching elements * @cat DOM/Traversing */ + + /** + * Removes any elements inside the array of elements from the set + * of matched elements. This method is used to remove one or more + * elements from a jQuery object. + * + * @example $("p").not( $("div p.selected") ) + * @before

Hello

Hello Again

+ * @result [

Hello

] + * @desc Removes all elements that match "div p.selected" from the total set of all paragraphs. + * + * @name not + * @type jQuery + * @param Array|jQuery elems A set of elements to remove from the jQuery set of matched elements. + * @cat DOM/Traversing + */ not: function(t) { - return this.pushStack( typeof t == "string" ? - jQuery.filter(t,this,true).r : - jQuery.grep(this,function(a){ return a != t; }) ); + return this.pushStack( + t.constructor == String && + jQuery.multiFilter(t,this,true) || + + jQuery.grep(this,function(a){ + if ( t.constructor == Array || t.jquery ) + return !jQuery.inArray( t, a ); + else + return a != t; + }) ); }, /** @@ -1007,7 +1021,9 @@ jQuery.fn = jQuery.prototype = { * @cat DOM/Attributes */ val: function( val ) { - return val == undefined ? ( this.length ? this[0].value : null ) : this.attr( "value", val ); + return val == undefined ? + ( this.length ? this[0].value : null ) : + this.attr( "value", val ); }, /** @@ -1037,7 +1053,9 @@ jQuery.fn = jQuery.prototype = { * @cat DOM/Attributes */ html: function( val ) { - return val == undefined ? ( this.length ? this[0].innerHTML : null ) : this.empty().append( val ); + return val == undefined ? + ( this.length ? this[0].innerHTML : null ) : + this.empty().append( val ); }, /** @@ -1828,7 +1846,7 @@ jQuery.each({ jQuery.fn[ i ] = function(a) { var ret = jQuery.map(this,n); if ( a && typeof a == "string" ) - ret = jQuery.filter(a,ret).r; + ret = jQuery.multiFilter(a,ret); return this.pushStack( ret ); }; }); diff --git a/src/selector/selector.js b/src/selector/selector.js index e21102c8d..1bad21b63 100644 --- a/src/selector/selector.js +++ b/src/selector/selector.js @@ -89,6 +89,24 @@ jQuery.extend({ } ], + multiFilter: function( expr, elems, not ) { + var old, cur = []; + + while ( expr && expr != old ) { +console.log( cur, expr, elems, not ); + var f = jQuery.filter( expr, elems, not ); + expr = f.t.replace(/^\s*,\s*/, "" ); + + if ( not ) + cur = elems = f.r; + else + cur = jQuery.merge( cur, f.r ); + } +console.log( "DONE", cur, expr, elems, not ); + + return cur; + }, + /** * @name $.find * @type Array