var runtil = /Until$/, rparentsprev = /^(?:parents|prev(?:Until|All))/, isSimple = /^.[^:#\[\.,]*$/, rneedsContext = jQuery.expr.match.needsContext, // methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend({ find: function( selector ) { var self, matched, i, l = this.length; if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { for ( i = 0; i < l; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } }) ); } matched = []; for ( i = 0; i < l; i++ ) { jQuery.find( selector, this[ i ], matched ); } // Needed because $( selector, context ) becomes $( context ).find( selector ) matched = this.pushStack( l > 1 ? jQuery.unique( matched ) : matched ); matched.selector = ( this.selector ? this.selector + " " : "" ) + selector; return matched; }, has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter(function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[i] ) ) { return true; } } }); }, not: function( selector ) { return this.pushStack( winnow(this, selector, false) ); }, filter: function( selector ) { return this.pushStack( winnow(this, selector, true) ); }, is: function( selector ) { return !!selector && ( typeof selector === "string" ? // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". rneedsContext.test( selector ) ? jQuery( selector, this.context ).index( this[ 0 ] ) >= 0 : jQuery.filter( selector, this ).length > 0 : this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ? jQuery( selectors, context || this.context ) : 0; for ( ; i < l; i++ ) { cur = this[ i ]; while ( cur && cur.ownerDocument && cur !== context ) { if ( pos ? pos.index( cur ) > -1 : jQuery.find.matchesSelector( cur, selectors ) ) { matched.push( cur ); break; } cur = cur.parentElement; } } return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); }, // Determine the position of an element within // the matched set of elements index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // index in selector if ( typeof elem === "string" ) { return core_indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return core_indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( jQuery.unique(all) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter(selector) ); } }); jQuery.fn.andSelf = jQuery.fn.addBack; jQuery.each({ parent: function( elem ) { return elem.parentElement; }, parents: function( elem ) { return jQuery.dir( elem, "parentElement" ); }, parentsUntil: function( elem, i, until ) { return jQuery.dir( elem, "parentElement", until ); }, next: function( elem ) { return elem.nextElementSibling; }, prev: function( elem ) { return elem.previousElementSibling; }, nextAll: function( elem ) { return jQuery.dir( elem, "nextElementSibling" ); }, prevAll: function( elem ) { return jQuery.dir( elem, "previousElementSibling" ); }, nextUntil: function( elem, i, until ) { return jQuery.dir( elem, "nextElementSibling", until ); }, prevUntil: function( elem, i, until ) { return jQuery.dir( elem, "previousElementSibling", until ); }, siblings: function( elem ) { return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { var children = elem.children; // documentFragment or document does not have children property return children ? jQuery.merge( [], children ) : jQuery.sibling( elem.firstChild ); }, contents: function( elem ) { return jQuery.nodeName( elem, "iframe" ) ? elem.contentDocument || elem.contentWindow.document : jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( !runtil.test( name ) ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { if ( !guaranteedUnique[ name ] ) { jQuery.unique( matched ); } if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; }); jQuery.extend({ filter: function( expr, elems, not ) { if ( not ) { expr = ":not(" + expr + ")"; } return elems.length === 1 ? jQuery.find.matchesSelector( elems[ 0 ], expr ) ? [ elems[ 0 ] ] : [] : jQuery.find.matches( expr, elems ); }, dir: function( elem, dir, until ) { var cur = elem[ dir ], matched = []; while ( cur && ( !until || !jQuery( cur ).is( until ) ) ) { matched.push( cur ); cur = cur[ dir ]; } return matched; }, sibling: function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; } }); // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; var filtered; if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); return retVal === keep; }); } if ( qualifier.nodeType ) { return jQuery.grep(elements, function( elem ) { return ( elem === qualifier ) === keep; }); } if ( typeof qualifier === "string" ) { filtered = jQuery.grep(elements, function( elem ) { return elem.nodeType === 1; }); if ( isSimple.test( qualifier ) ) { return jQuery.filter( qualifier, filtered, !keep ); } qualifier = jQuery.filter( qualifier, filtered ); } return jQuery.grep(elements, function( elem ) { return ( core_indexOf.call( qualifier, elem ) >= 0 ) === keep; }); }