blob: de377188f5b92e9eed795237f230d915b56af674 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001define( [
2 "./core",
Renovate botf591dcf2023-12-30 14:13:54 +00003 "./var/getProto",
Copybara botbe50d492023-11-30 00:16:42 +01004 "./var/indexOf",
5 "./traversing/var/dir",
6 "./traversing/var/siblings",
7 "./traversing/var/rneedsContext",
8 "./core/nodeName",
9
10 "./core/init",
11 "./traversing/findFilter",
12 "./selector"
Renovate botf591dcf2023-12-30 14:13:54 +000013], function( jQuery, getProto, indexOf, dir, siblings, rneedsContext, nodeName ) {
Copybara botbe50d492023-11-30 00:16:42 +010014
15"use strict";
16
17var rparentsprev = /^(?:parents|prev(?:Until|All))/,
18
19 // Methods guaranteed to produce a unique set when starting from a unique set
20 guaranteedUnique = {
21 children: true,
22 contents: true,
23 next: true,
24 prev: true
25 };
26
27jQuery.fn.extend( {
28 has: function( target ) {
29 var targets = jQuery( target, this ),
30 l = targets.length;
31
32 return this.filter( function() {
33 var i = 0;
34 for ( ; i < l; i++ ) {
35 if ( jQuery.contains( this, targets[ i ] ) ) {
36 return true;
37 }
38 }
39 } );
40 },
41
42 closest: function( selectors, context ) {
43 var cur,
44 i = 0,
45 l = this.length,
46 matched = [],
47 targets = typeof selectors !== "string" && jQuery( selectors );
48
49 // Positional selectors never match, since there's no _selection_ context
50 if ( !rneedsContext.test( selectors ) ) {
51 for ( ; i < l; i++ ) {
52 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
53
54 // Always skip document fragments
55 if ( cur.nodeType < 11 && ( targets ?
56 targets.index( cur ) > -1 :
57
58 // Don't pass non-elements to Sizzle
59 cur.nodeType === 1 &&
60 jQuery.find.matchesSelector( cur, selectors ) ) ) {
61
62 matched.push( cur );
63 break;
64 }
65 }
66 }
67 }
68
69 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
70 },
71
72 // Determine the position of an element within the set
73 index: function( elem ) {
74
75 // No argument, return index in parent
76 if ( !elem ) {
77 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
78 }
79
80 // Index in selector
81 if ( typeof elem === "string" ) {
82 return indexOf.call( jQuery( elem ), this[ 0 ] );
83 }
84
85 // Locate the position of the desired element
86 return indexOf.call( this,
87
88 // If it receives a jQuery object, the first element is used
89 elem.jquery ? elem[ 0 ] : elem
90 );
91 },
92
93 add: function( selector, context ) {
94 return this.pushStack(
95 jQuery.uniqueSort(
96 jQuery.merge( this.get(), jQuery( selector, context ) )
97 )
98 );
99 },
100
101 addBack: function( selector ) {
102 return this.add( selector == null ?
103 this.prevObject : this.prevObject.filter( selector )
104 );
105 }
106} );
107
108function sibling( cur, dir ) {
109 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
110 return cur;
111}
112
113jQuery.each( {
114 parent: function( elem ) {
115 var parent = elem.parentNode;
116 return parent && parent.nodeType !== 11 ? parent : null;
117 },
118 parents: function( elem ) {
119 return dir( elem, "parentNode" );
120 },
Renovate botf591dcf2023-12-30 14:13:54 +0000121 parentsUntil: function( elem, _i, until ) {
Copybara botbe50d492023-11-30 00:16:42 +0100122 return dir( elem, "parentNode", until );
123 },
124 next: function( elem ) {
125 return sibling( elem, "nextSibling" );
126 },
127 prev: function( elem ) {
128 return sibling( elem, "previousSibling" );
129 },
130 nextAll: function( elem ) {
131 return dir( elem, "nextSibling" );
132 },
133 prevAll: function( elem ) {
134 return dir( elem, "previousSibling" );
135 },
Renovate botf591dcf2023-12-30 14:13:54 +0000136 nextUntil: function( elem, _i, until ) {
Copybara botbe50d492023-11-30 00:16:42 +0100137 return dir( elem, "nextSibling", until );
138 },
Renovate botf591dcf2023-12-30 14:13:54 +0000139 prevUntil: function( elem, _i, until ) {
Copybara botbe50d492023-11-30 00:16:42 +0100140 return dir( elem, "previousSibling", until );
141 },
142 siblings: function( elem ) {
143 return siblings( ( elem.parentNode || {} ).firstChild, elem );
144 },
145 children: function( elem ) {
146 return siblings( elem.firstChild );
147 },
148 contents: function( elem ) {
Renovate botf591dcf2023-12-30 14:13:54 +0000149 if ( elem.contentDocument != null &&
150
151 // Support: IE 11+
152 // <object> elements with no `data` attribute has an object
153 // `contentDocument` with a `null` prototype.
154 getProto( elem.contentDocument ) ) {
155
Copybara botbe50d492023-11-30 00:16:42 +0100156 return elem.contentDocument;
157 }
158
159 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
160 // Treat the template element as a regular one in browsers that
161 // don't support it.
162 if ( nodeName( elem, "template" ) ) {
163 elem = elem.content || elem;
164 }
165
166 return jQuery.merge( [], elem.childNodes );
167 }
168}, function( name, fn ) {
169 jQuery.fn[ name ] = function( until, selector ) {
170 var matched = jQuery.map( this, fn, until );
171
172 if ( name.slice( -5 ) !== "Until" ) {
173 selector = until;
174 }
175
176 if ( selector && typeof selector === "string" ) {
177 matched = jQuery.filter( selector, matched );
178 }
179
180 if ( this.length > 1 ) {
181
182 // Remove duplicates
183 if ( !guaranteedUnique[ name ] ) {
184 jQuery.uniqueSort( matched );
185 }
186
187 // Reverse order for parents* and prev-derivatives
188 if ( rparentsprev.test( name ) ) {
189 matched.reverse();
190 }
191 }
192
193 return this.pushStack( matched );
194 };
195} );
196
197return jQuery;
198} );