jquery or

an addition I suggested here http://forum.jquery.com/topic/traversing-or

by naugtur

HTML

<p>======New updated version======<br/>
    what links here:<br/> <a href="http://bugs.jquery.com/ticket/7194">http://bugs.jquery.com/ticket/7194</a><br/>
    <a href="http://forum.jquery.com/topic/traversing-or">http://forum.jquery.com/topic/traversing-or</a>
    <a href="http://stackoverflow.com/questions/3764794/can-i-access-a-name-of-last-used-traversing-operation-in-a-chain">stackoverflow.com question</a>
</p>

<div class="a">
    
    <p>There is a common case as follows:
    </p>
    <pre>
    $elem=$this.find('someselector');
    if($elem.length==0){
    $elem=$this.find('otherselector');
    }
    </pre><p>
    This can be abbreviated to a simple statement:
    </p><pre>
    $elem=$this.find('someselector').or('otherselector');
    </pre>
</div>
<div style="color:orange">
    This test requires firebug.</div><div> <br/> Expected console output:<pre>
  [div.a]
  [div.a]
  [div.a]
  [p, p]
  [div.a]
  body
  This test requires firebug. </pre>
</div>

JavaScript

//Following functions are under MIT licence
//Author: Zbigniew Tenerowicz
        
    $.fn.log=function(a){try{console.log(a)}catch(e){};return this}
        
    $.fn.or=function(a){var t=this;return t.length>0?t:(t=t.end())&&$.isFunction(a)?a.apply(t):a?t.find(a):t}
        
    $.fn.or2=function(a){ //this is not yet fully tested
    var t=this,s=t.selector;    
    return t.length>0?t:(t=t.end())&&$.isFunction(a)?a.apply(t):a?(function(){
        s=s.replace(/^.*\.([a-z]+)\([^()]*\)[^ ()]*$|.*/i,'$1');
        return t[s?s:'find'](a);
    })():t}
    
                        
            $(document).ready(function(){
            
            console.log('---start---');
            console.log( $('.a').or('.b') );
            //does not use the selector .b if .a was found
                                     
            console.log( $('.b').or('.a') );  
            //there was no .b, .a is selected
                                     
            console.log( $(document).find('.b').or('.a') );
            //also with traversing (that should be obvious)

            console.log('misbehaviour issue');
            //TODO? misbehaviour - I'd expect it to use children not find
            console.log( $('body').children('.b').or('p') );
            //Fixed misbehaviour - it does use children. For me it's more intuitive, but I'm not sure if it's worth it
            console.log( $('body').children('.b').or2('p') );
            console.log('/misbehaviour issue');
            
            console.log( $('.a').or(function(){
                return $(this).selector
                }) ); //does not return the selector if .a was found
                
            console.log( $('body').find('.b').or(function(){
                return $(this).selector
                }) );  //if there's no .b it returns the body selector
                
            console.log( $(document).find('.b').or(function(){
                return $(this).find('.a').next()
               ...