Build: Fix pre release matching in compare size regex
[jquery.git] / src / traversing.js
blob374c4b794fbfebf529c2b28ebc48cd1c2ae6e0d0
1 import { jQuery } from "./core.js";
2 import { getProto } from "./var/getProto.js";
3 import { indexOf } from "./var/indexOf.js";
4 import { dir } from "./traversing/var/dir.js";
5 import { siblings } from "./traversing/var/siblings.js";
6 import { rneedsContext } from "./traversing/var/rneedsContext.js";
7 import { nodeName } from "./core/nodeName.js";
9 import "./core/init.js";
10 import "./traversing/findFilter.js";
11 import "./selector.js";
13 var rparentsprev = /^(?:parents|prev(?:Until|All))/,
15         // Methods guaranteed to produce a unique set when starting from a unique set
16         guaranteedUnique = {
17                 children: true,
18                 contents: true,
19                 next: true,
20                 prev: true
21         };
23 jQuery.fn.extend( {
24         has: function( target ) {
25                 var targets = jQuery( target, this ),
26                         l = targets.length;
28                 return this.filter( function() {
29                         var i = 0;
30                         for ( ; i < l; i++ ) {
31                                 if ( jQuery.contains( this, targets[ i ] ) ) {
32                                         return true;
33                                 }
34                         }
35                 } );
36         },
38         closest: function( selectors, context ) {
39                 var cur,
40                         i = 0,
41                         l = this.length,
42                         matched = [],
43                         targets = typeof selectors !== "string" && jQuery( selectors );
45                 // Positional selectors never match, since there's no _selection_ context
46                 if ( !rneedsContext.test( selectors ) ) {
47                         for ( ; i < l; i++ ) {
48                                 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
50                                         // Always skip document fragments
51                                         if ( cur.nodeType < 11 && ( targets ?
52                                                 targets.index( cur ) > -1 :
54                                                 // Don't pass non-elements to jQuery#find
55                                                 cur.nodeType === 1 &&
56                                                         jQuery.find.matchesSelector( cur, selectors ) ) ) {
58                                                 matched.push( cur );
59                                                 break;
60                                         }
61                                 }
62                         }
63                 }
65                 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
66         },
68         // Determine the position of an element within the set
69         index: function( elem ) {
71                 // No argument, return index in parent
72                 if ( !elem ) {
73                         return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
74                 }
76                 // Index in selector
77                 if ( typeof elem === "string" ) {
78                         return indexOf.call( jQuery( elem ), this[ 0 ] );
79                 }
81                 // Locate the position of the desired element
82                 return indexOf.call( this,
84                         // If it receives a jQuery object, the first element is used
85                         elem.jquery ? elem[ 0 ] : elem
86                 );
87         },
89         add: function( selector, context ) {
90                 return this.pushStack(
91                         jQuery.uniqueSort(
92                                 jQuery.merge( this.get(), jQuery( selector, context ) )
93                         )
94                 );
95         },
97         addBack: function( selector ) {
98                 return this.add( selector == null ?
99                         this.prevObject : this.prevObject.filter( selector )
100                 );
101         }
102 } );
104 function sibling( cur, dir ) {
105         while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
106         return cur;
109 jQuery.each( {
110         parent: function( elem ) {
111                 var parent = elem.parentNode;
112                 return parent && parent.nodeType !== 11 ? parent : null;
113         },
114         parents: function( elem ) {
115                 return dir( elem, "parentNode" );
116         },
117         parentsUntil: function( elem, _i, until ) {
118                 return dir( elem, "parentNode", until );
119         },
120         next: function( elem ) {
121                 return sibling( elem, "nextSibling" );
122         },
123         prev: function( elem ) {
124                 return sibling( elem, "previousSibling" );
125         },
126         nextAll: function( elem ) {
127                 return dir( elem, "nextSibling" );
128         },
129         prevAll: function( elem ) {
130                 return dir( elem, "previousSibling" );
131         },
132         nextUntil: function( elem, _i, until ) {
133                 return dir( elem, "nextSibling", until );
134         },
135         prevUntil: function( elem, _i, until ) {
136                 return dir( elem, "previousSibling", until );
137         },
138         siblings: function( elem ) {
139                 return siblings( ( elem.parentNode || {} ).firstChild, elem );
140         },
141         children: function( elem ) {
142                 return siblings( elem.firstChild );
143         },
144         contents: function( elem ) {
145                 if ( elem.contentDocument != null &&
147                         // Support: IE 11+
148                         // <object> elements with no `data` attribute has an object
149                         // `contentDocument` with a `null` prototype.
150                         getProto( elem.contentDocument ) ) {
152                         return elem.contentDocument;
153                 }
155                 // Support: IE 9 - 11+
156                 // Treat the template element as a regular one in browsers that
157                 // don't support it.
158                 if ( nodeName( elem, "template" ) ) {
159                         elem = elem.content || elem;
160                 }
162                 return jQuery.merge( [], elem.childNodes );
163         }
164 }, function( name, fn ) {
165         jQuery.fn[ name ] = function( until, selector ) {
166                 var matched = jQuery.map( this, fn, until );
168                 if ( name.slice( -5 ) !== "Until" ) {
169                         selector = until;
170                 }
172                 if ( selector && typeof selector === "string" ) {
173                         matched = jQuery.filter( selector, matched );
174                 }
176                 if ( this.length > 1 ) {
178                         // Remove duplicates
179                         if ( !guaranteedUnique[ name ] ) {
180                                 jQuery.uniqueSort( matched );
181                         }
183                         // Reverse order for parents* and prev-derivatives
184                         if ( rparentsprev.test( name ) ) {
185                                 matched.reverse();
186                         }
187                 }
189                 return this.pushStack( matched );
190         };
191 } );
193 export { jQuery, jQuery as $ };