Tests: include github ref in concurrency group
[jquery.git] / src / core.js
blobc7945550719cdf830243be18ae2298490fd33091
1 import { arr } from "./var/arr.js";
2 import { getProto } from "./var/getProto.js";
3 import { slice } from "./var/slice.js";
4 import { flat } from "./var/flat.js";
5 import { push } from "./var/push.js";
6 import { indexOf } from "./var/indexOf.js";
7 import { class2type } from "./var/class2type.js";
8 import { toString } from "./var/toString.js";
9 import { hasOwn } from "./var/hasOwn.js";
10 import { fnToString } from "./var/fnToString.js";
11 import { ObjectFunctionString } from "./var/ObjectFunctionString.js";
12 import { support } from "./var/support.js";
13 import { isArrayLike } from "./core/isArrayLike.js";
14 import { DOMEval } from "./core/DOMEval.js";
16 var version = "@VERSION",
18         rhtmlSuffix = /HTML$/i,
20         // Define a local copy of jQuery
21         jQuery = function( selector, context ) {
23                 // The jQuery object is actually just the init constructor 'enhanced'
24                 // Need init if jQuery is called (just allow error to be thrown if not included)
25                 return new jQuery.fn.init( selector, context );
26         };
28 jQuery.fn = jQuery.prototype = {
30         // The current version of jQuery being used
31         jquery: version,
33         constructor: jQuery,
35         // The default length of a jQuery object is 0
36         length: 0,
38         toArray: function() {
39                 return slice.call( this );
40         },
42         // Get the Nth element in the matched element set OR
43         // Get the whole matched element set as a clean array
44         get: function( num ) {
46                 // Return all the elements in a clean array
47                 if ( num == null ) {
48                         return slice.call( this );
49                 }
51                 // Return just the one element from the set
52                 return num < 0 ? this[ num + this.length ] : this[ num ];
53         },
55         // Take an array of elements and push it onto the stack
56         // (returning the new matched element set)
57         pushStack: function( elems ) {
59                 // Build a new jQuery matched element set
60                 var ret = jQuery.merge( this.constructor(), elems );
62                 // Add the old object onto the stack (as a reference)
63                 ret.prevObject = this;
65                 // Return the newly-formed element set
66                 return ret;
67         },
69         // Execute a callback for every element in the matched set.
70         each: function( callback ) {
71                 return jQuery.each( this, callback );
72         },
74         map: function( callback ) {
75                 return this.pushStack( jQuery.map( this, function( elem, i ) {
76                         return callback.call( elem, i, elem );
77                 } ) );
78         },
80         slice: function() {
81                 return this.pushStack( slice.apply( this, arguments ) );
82         },
84         first: function() {
85                 return this.eq( 0 );
86         },
88         last: function() {
89                 return this.eq( -1 );
90         },
92         even: function() {
93                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
94                         return ( i + 1 ) % 2;
95                 } ) );
96         },
98         odd: function() {
99                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
100                         return i % 2;
101                 } ) );
102         },
104         eq: function( i ) {
105                 var len = this.length,
106                         j = +i + ( i < 0 ? len : 0 );
107                 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
108         },
110         end: function() {
111                 return this.prevObject || this.constructor();
112         }
115 jQuery.extend = jQuery.fn.extend = function() {
116         var options, name, src, copy, copyIsArray, clone,
117                 target = arguments[ 0 ] || {},
118                 i = 1,
119                 length = arguments.length,
120                 deep = false;
122         // Handle a deep copy situation
123         if ( typeof target === "boolean" ) {
124                 deep = target;
126                 // Skip the boolean and the target
127                 target = arguments[ i ] || {};
128                 i++;
129         }
131         // Handle case when target is a string or something (possible in deep copy)
132         if ( typeof target !== "object" && typeof target !== "function" ) {
133                 target = {};
134         }
136         // Extend jQuery itself if only one argument is passed
137         if ( i === length ) {
138                 target = this;
139                 i--;
140         }
142         for ( ; i < length; i++ ) {
144                 // Only deal with non-null/undefined values
145                 if ( ( options = arguments[ i ] ) != null ) {
147                         // Extend the base object
148                         for ( name in options ) {
149                                 copy = options[ name ];
151                                 // Prevent Object.prototype pollution
152                                 // Prevent never-ending loop
153                                 if ( name === "__proto__" || target === copy ) {
154                                         continue;
155                                 }
157                                 // Recurse if we're merging plain objects or arrays
158                                 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
159                                         ( copyIsArray = Array.isArray( copy ) ) ) ) {
160                                         src = target[ name ];
162                                         // Ensure proper type for the source value
163                                         if ( copyIsArray && !Array.isArray( src ) ) {
164                                                 clone = [];
165                                         } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
166                                                 clone = {};
167                                         } else {
168                                                 clone = src;
169                                         }
170                                         copyIsArray = false;
172                                         // Never move original objects, clone them
173                                         target[ name ] = jQuery.extend( deep, clone, copy );
175                                 // Don't bring in undefined values
176                                 } else if ( copy !== undefined ) {
177                                         target[ name ] = copy;
178                                 }
179                         }
180                 }
181         }
183         // Return the modified object
184         return target;
187 jQuery.extend( {
189         // Unique for each copy of jQuery on the page
190         expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
192         // Assume jQuery is ready without the ready module
193         isReady: true,
195         error: function( msg ) {
196                 throw new Error( msg );
197         },
199         noop: function() {},
201         isPlainObject: function( obj ) {
202                 var proto, Ctor;
204                 // Detect obvious negatives
205                 // Use toString instead of jQuery.type to catch host objects
206                 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
207                         return false;
208                 }
210                 proto = getProto( obj );
212                 // Objects with no prototype (e.g., `Object.create( null )`) are plain
213                 if ( !proto ) {
214                         return true;
215                 }
217                 // Objects with prototype are plain iff they were constructed by a global Object function
218                 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
219                 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
220         },
222         isEmptyObject: function( obj ) {
223                 var name;
225                 for ( name in obj ) {
226                         return false;
227                 }
228                 return true;
229         },
231         // Evaluates a script in a provided context; falls back to the global one
232         // if not specified.
233         globalEval: function( code, options, doc ) {
234                 DOMEval( code, { nonce: options && options.nonce }, doc );
235         },
237         each: function( obj, callback ) {
238                 var length, i = 0;
240                 if ( isArrayLike( obj ) ) {
241                         length = obj.length;
242                         for ( ; i < length; i++ ) {
243                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
244                                         break;
245                                 }
246                         }
247                 } else {
248                         for ( i in obj ) {
249                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
250                                         break;
251                                 }
252                         }
253                 }
255                 return obj;
256         },
259         // Retrieve the text value of an array of DOM nodes
260         text: function( elem ) {
261                 var node,
262                         ret = "",
263                         i = 0,
264                         nodeType = elem.nodeType;
266                 if ( !nodeType ) {
268                         // If no nodeType, this is expected to be an array
269                         while ( ( node = elem[ i++ ] ) ) {
271                                 // Do not traverse comment nodes
272                                 ret += jQuery.text( node );
273                         }
274                 }
275                 if ( nodeType === 1 || nodeType === 11 ) {
276                         return elem.textContent;
277                 }
278                 if ( nodeType === 9 ) {
279                         return elem.documentElement.textContent;
280                 }
281                 if ( nodeType === 3 || nodeType === 4 ) {
282                         return elem.nodeValue;
283                 }
285                 // Do not include comment or processing instruction nodes
287                 return ret;
288         },
291         // results is for internal usage only
292         makeArray: function( arr, results ) {
293                 var ret = results || [];
295                 if ( arr != null ) {
296                         if ( isArrayLike( Object( arr ) ) ) {
297                                 jQuery.merge( ret,
298                                         typeof arr === "string" ?
299                                                 [ arr ] : arr
300                                 );
301                         } else {
302                                 push.call( ret, arr );
303                         }
304                 }
306                 return ret;
307         },
309         inArray: function( elem, arr, i ) {
310                 return arr == null ? -1 : indexOf.call( arr, elem, i );
311         },
313         isXMLDoc: function( elem ) {
314                 var namespace = elem && elem.namespaceURI,
315                         docElem = elem && ( elem.ownerDocument || elem ).documentElement;
317                 // Assume HTML when documentElement doesn't yet exist, such as inside
318                 // document fragments.
319                 return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );
320         },
322         // Note: an element does not contain itself
323         contains: function( a, b ) {
324                 var bup = b && b.parentNode;
326                 return a === bup || !!( bup && bup.nodeType === 1 && (
328                         // Support: IE 9 - 11+
329                         // IE doesn't have `contains` on SVG.
330                         a.contains ?
331                                 a.contains( bup ) :
332                                 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
333                 ) );
334         },
336         merge: function( first, second ) {
337                 var len = +second.length,
338                         j = 0,
339                         i = first.length;
341                 for ( ; j < len; j++ ) {
342                         first[ i++ ] = second[ j ];
343                 }
345                 first.length = i;
347                 return first;
348         },
350         grep: function( elems, callback, invert ) {
351                 var callbackInverse,
352                         matches = [],
353                         i = 0,
354                         length = elems.length,
355                         callbackExpect = !invert;
357                 // Go through the array, only saving the items
358                 // that pass the validator function
359                 for ( ; i < length; i++ ) {
360                         callbackInverse = !callback( elems[ i ], i );
361                         if ( callbackInverse !== callbackExpect ) {
362                                 matches.push( elems[ i ] );
363                         }
364                 }
366                 return matches;
367         },
369         // arg is for internal usage only
370         map: function( elems, callback, arg ) {
371                 var length, value,
372                         i = 0,
373                         ret = [];
375                 // Go through the array, translating each of the items to their new values
376                 if ( isArrayLike( elems ) ) {
377                         length = elems.length;
378                         for ( ; i < length; i++ ) {
379                                 value = callback( elems[ i ], i, arg );
381                                 if ( value != null ) {
382                                         ret.push( value );
383                                 }
384                         }
386                 // Go through every key on the object,
387                 } else {
388                         for ( i in elems ) {
389                                 value = callback( elems[ i ], i, arg );
391                                 if ( value != null ) {
392                                         ret.push( value );
393                                 }
394                         }
395                 }
397                 // Flatten any nested arrays
398                 return flat( ret );
399         },
401         // A global GUID counter for objects
402         guid: 1,
404         // jQuery.support is not used in Core but other projects attach their
405         // properties to it so it needs to exist.
406         support: support
407 } );
409 if ( typeof Symbol === "function" ) {
410         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
413 // Populate the class2type map
414 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
415         function( _i, name ) {
416                 class2type[ "[object " + name + "]" ] = name.toLowerCase();
417         } );
419 export { jQuery, jQuery as $ };