Added .filter("expr",ifCallback,elseCallback) (works for find, not, clone, add, etc.).
[jquery.git] / src / jquery / jquery.js
index 70c3c60..cda8fae 100644 (file)
@@ -667,12 +667,6 @@ jQuery.fn = jQuery.prototype = {
         * var result = $('#first').append('<b>buga</b>');
         * ok( result.text() == defaultText + 'buga', 'Check if text appending works' );
         *
-        * reset();
-        * var expected = "Try them out: bla ";
-        * $('#first').append(" ");
-        * $('#first').append("bla ");
-        * ok( expected == $('#first').text(), "Check for appending of spaces" );
-        *
         * @name append
         * @type jQuery
         * @param String html A string of HTML, that will be created on the fly and appended to the target.
@@ -982,6 +976,12 @@ jQuery.fn = jQuery.prototype = {
         * @result $("p").filter(".selected") == [ <p class="selected">Hello</p> ]
         *
         * @test isSet( $("input").filter(":checked").get(), q("radio2", "check1"), "Filter elements" );
+        * @test $("input").filter(":checked",function(i){ 
+        *   ok( this == q("radio2", "check1")[i], "Filter elements, context" );
+        * });
+        * @test $("#main > p#ap > a").filter("#foobar",function(){},function(i){
+        *   ok( this == q("google","groups", "mark")[i], "Filter elements, else context" );
+        * });
         *
         * @name filter
         * @type jQuery
@@ -1047,6 +1047,7 @@ jQuery.fn = jQuery.prototype = {
         * @example $("p").not("#selected")
         * @before <p>Hello</p><p id="selected">Hello Again</p>
         * @result [ <p>Hello</p> ]
+        *
         * @test ok($("#main > p#ap > a").not("#google").length == 2, ".not")
         *
         * @name not
@@ -1157,6 +1158,52 @@ jQuery.fn = jQuery.prototype = {
        is: function(expr) {
                return expr ? jQuery.filter(expr,this).r.length > 0 : false;
        },
+       
+       /**
+        * Executes the first callback for every element that fits the expression
+        * and executes the second callback for every element that does not fit
+        * the expression.
+        *
+        * @example $('div').ifelse(':visible',
+     *   function() { $(this).slideUp(); },
+         function() { $(this).slideDown(); }
+     * );
+        * @desc Slides down all visible div elements and slides down all others
+        * 
+        * @test var checked = 0, notChecked = 0;
+        * var inputChecked = $(':input').ifelse(':checked',
+        *   function() { checked++; },
+        *   function() { notChecked++ }
+        * );
+        * ok( checked == 2, 'Check is if/else: Count checked elements' );
+        * ok( notChecked == 12, 'Check is if/else: Count unchecked elements' );
+        *
+        * $('#first, #foo, #ap').ifelse('p',
+        *   function() { $(this).html('me == p') },
+        *   function() { $(this).html('me != p') }
+        * );
+        * ok( $('#first').text() == 'me == p', 'Check filter-if-clause' );
+        * ok( $('#foo').text() == 'me != p', 'Check else-clause' );
+        * ok( $('#ap').text() == 'me == p', 'Check filter-if-clause' );
+        *
+        * @name ifelse
+        * @type jQuery
+        * @param String expression The expression with which to filter
+        * @param Function ifCallback Called for elements that fit the expression
+        * @param Function elseCallback Called for elements that don't fit the expression
+        * @cat DOM/Traversing
+        */
+       ifelse: function(expr, ifCallback, elseCallback) {
+               var ifCallback = ifCallback || function() {};
+        var elseCalllback = elseCallback || function() {};
+        return this.each(function() {
+            if($(this).is(expr)) {
+                ifCallback.apply(this);
+            } else {
+                elseCallback.apply(this);
+            }
+        });
+       },
 
        /**
         *
@@ -1206,17 +1253,23 @@ jQuery.fn = jQuery.prototype = {
         */
        pushStack: function(a,args) {
                var fn = args && args[args.length-1];
+               var fn2 = args && args[args.length-2];
+               
+               if ( fn && fn.constructor != Function ) fn = null;
+               if ( fn2 && fn2.constructor != Function ) fn2 = null;
 
-               if ( !fn || fn.constructor != Function ) {
+               if ( !fn ) {
                        if ( !this.stack ) this.stack = [];
                        this.stack.push( this.get() );
                        this.get( a );
                } else {
                        var old = this.get();
                        this.get( a );
-                       if ( typeof fn == "function" )
-                               this.each( fn );
-                       this.get( old );
+
+                       if ( fn2 && a.length || !fn2 )
+                               this.each( fn2 || fn ).get( old );
+                       else
+                               this.get( old ).each( fn );
                }
 
                return this;
@@ -1824,6 +1877,8 @@ jQuery.extend({
                if ( fix[name] ) {
                        if ( value != undefined ) elem[fix[name]] = value;
                        return elem[fix[name]];
+               } else if( value == undefined && $.browser.msie && elem.nodeName && elem.nodeName.toUpperCase() == 'FORM' && (name == 'action' || name == 'method') ) {
+                       return elem.getAttributeNode(name).nodeValue;
                } else if ( elem.getAttribute != undefined ) {
                        if ( value != undefined ) elem.setAttribute( name, value );
                        return elem.getAttribute( name, 2 );
@@ -1837,13 +1892,13 @@ jQuery.extend({
        // The regular expressions that power the parsing engine
        parse: [
                // Match: [@value='test'], [@foo]
-               "\\[ *(@)S *([!*$^=]*)Q\\]",
+               "\\[ *(@)S *([!*$^=]*) *('?\"?)(.*?)\\4 *\\]",
 
                // Match: [div], [div p]
-               "(\\[)Q\\]",
+               "(\\[)\s*(.*?)\s*\\]",
 
                // Match: :contains('foo')
-               "(:)S\\(Q\\)",
+               "(:)S\\(\"?'?([^\\)]*?)\"?'?\\)",
 
                // Match: :even, :last-chlid
                "([:.#]*)S"
@@ -1859,28 +1914,19 @@ jQuery.extend({
                        var p = jQuery.parse;
 
                        for ( var i = 0; i < p.length; i++ ) {
-                               // get number for backreference
-                               var br = 0;
-                               if(p[i].indexOf('Q') != -1){
-                                       br = p[i].replace(/\\\(/g,'').match(/\(|S/g).length+1;
-                               }
-                               var re = new RegExp( "^" + p[i]
-                       
-                                       // Look for a string-like sequence
-                                       .replace( 'S', "([a-z*_-][a-z0-9_-]*)" )
-
-                                       // Look for something (optionally) enclosed with quotes
-                                       .replace( 'Q', " *('|\"|)([^'\"]*?)\\"+br+" *" ), "i" );
+               
+                               // Look for, and replace, string-like sequences
+                               // and finally build a regexp out of it
+                               var re = new RegExp(
+                                       "^" + p[i].replace("S", "([a-z*_-][a-z0-9_-]*)"), "i" );
 
                                var m = re.exec( t );
 
                                if ( m ) {
-                                       // Re-organize the match
-                                       if(br == 4){
+                                       // Re-organize the first match
+                                       if ( !i )
                                                m = ["",m[1], m[3], m[2], m[5]];
-                                       } else if(br != 0) {
-                                               m.splice(br,1);
-                                       }
+
                                        // Remove what we just matched
                                        t = t.replace( re, "" );