Make sure closest works on disconnected DOM nodes. Fixes #7142.
[jquery.git] / src / traversing.js
index 1633e2e..5a479f2 100644 (file)
@@ -6,9 +6,8 @@ var runtil = /Until$/,
        rmultiselector = /,/,
        rchild = /^\s*>/,
        isSimple = /^.[^:#\[\.,]*$/,
-       slice = Array.prototype.slice;
-
-var POS = jQuery.expr.match.POS;
+       slice = Array.prototype.slice,
+       POS = jQuery.expr.match.POS;
 
 jQuery.fn.extend({
        find: function( selector ) {
@@ -63,14 +62,13 @@ jQuery.fn.extend({
        },
 
        closest: function( selectors, context ) {
-               var ret;
+               var ret = [], i, l, cur = this[0];
 
                if ( jQuery.isArray( selectors ) ) {
-                       var cur = this[0], match, matches = {}, selector, level = 1;
-                       ret = [];
+                       var match, matches = {}, selector, level = 1;
 
                        if ( cur && selectors.length ) {
-                               for ( var i = 0, l = selectors.length; i < l; i++ ) {
+                               for ( i = 0, l = selectors.length; i < l; i++ ) {
                                        selector = selectors[i];
 
                                        if ( !matches[selector] ) {
@@ -100,23 +98,22 @@ jQuery.fn.extend({
                var pos = POS.test( selectors ) ? 
                        jQuery( selectors, context || this.context ) : null;
 
-    var ret = [];
-
-    for ( var i=0,j=this.length; i<j; i++ ) {
-      var cur = this[i];
+               for ( i = 0, l = this.length; i < l; i++ ) {
+                       cur = this[i];
 
-      while ( cur ) {
-        if ( pos ? pos.index(cur) > -1 : jQuery.find.matches(selectors, [cur]).length ) {
+                       while ( cur ) {
+                               if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
                                        ret.push( cur );
-          break;
+                                       break;
+
                                } else {
-          cur = cur.parentNode;
-          if ( !cur.ownerDocument || cur === context ) {
-            break;
-          }
-        }
-      }
-    }
+                                       cur = cur.parentNode;
+                                       if ( !cur || !cur.ownerDocument || cur === context ) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
 
                ret = ret.length > 1 ? jQuery.unique(ret) : ret;
                
@@ -228,7 +225,9 @@ jQuery.extend({
                        expr = ":not(" + expr + ")";
                }
 
-               return jQuery.find.matches(expr, elems);
+               return elems.length === 1 ?
+                       jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+                       jQuery.find.matches(expr, elems);
        },
        
        dir: function( elem, dir, until ) {