Docs: Update webpack website in README
[jquery.git] / src / core.js
blob4f5731ae1b90656f1655449deb0b4fdd4b84d4ca
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                 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
275                         return elem.textContent;
276                 } else if ( nodeType === 3 || nodeType === 4 ) {
277                         return elem.nodeValue;
278                 }
280                 // Do not include comment or processing instruction nodes
282                 return ret;
283         },
286         // results is for internal usage only
287         makeArray: function( arr, results ) {
288                 var ret = results || [];
290                 if ( arr != null ) {
291                         if ( isArrayLike( Object( arr ) ) ) {
292                                 jQuery.merge( ret,
293                                         typeof arr === "string" ?
294                                                 [ arr ] : arr
295                                 );
296                         } else {
297                                 push.call( ret, arr );
298                         }
299                 }
301                 return ret;
302         },
304         inArray: function( elem, arr, i ) {
305                 return arr == null ? -1 : indexOf.call( arr, elem, i );
306         },
308         isXMLDoc: function( elem ) {
309                 var namespace = elem && elem.namespaceURI,
310                         docElem = elem && ( elem.ownerDocument || elem ).documentElement;
312                 // Assume HTML when documentElement doesn't yet exist, such as inside
313                 // document fragments.
314                 return !rhtmlSuffix.test( namespace || docElem && docElem.nodeName || "HTML" );
315         },
317         merge: function( first, second ) {
318                 var len = +second.length,
319                         j = 0,
320                         i = first.length;
322                 for ( ; j < len; j++ ) {
323                         first[ i++ ] = second[ j ];
324                 }
326                 first.length = i;
328                 return first;
329         },
331         grep: function( elems, callback, invert ) {
332                 var callbackInverse,
333                         matches = [],
334                         i = 0,
335                         length = elems.length,
336                         callbackExpect = !invert;
338                 // Go through the array, only saving the items
339                 // that pass the validator function
340                 for ( ; i < length; i++ ) {
341                         callbackInverse = !callback( elems[ i ], i );
342                         if ( callbackInverse !== callbackExpect ) {
343                                 matches.push( elems[ i ] );
344                         }
345                 }
347                 return matches;
348         },
350         // arg is for internal usage only
351         map: function( elems, callback, arg ) {
352                 var length, value,
353                         i = 0,
354                         ret = [];
356                 // Go through the array, translating each of the items to their new values
357                 if ( isArrayLike( elems ) ) {
358                         length = elems.length;
359                         for ( ; i < length; i++ ) {
360                                 value = callback( elems[ i ], i, arg );
362                                 if ( value != null ) {
363                                         ret.push( value );
364                                 }
365                         }
367                 // Go through every key on the object,
368                 } else {
369                         for ( i in elems ) {
370                                 value = callback( elems[ i ], i, arg );
372                                 if ( value != null ) {
373                                         ret.push( value );
374                                 }
375                         }
376                 }
378                 // Flatten any nested arrays
379                 return flat( ret );
380         },
382         // A global GUID counter for objects
383         guid: 1,
385         // jQuery.support is not used in Core but other projects attach their
386         // properties to it so it needs to exist.
387         support: support
388 } );
390 if ( typeof Symbol === "function" ) {
391         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
394 // Populate the class2type map
395 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
396         function( _i, name ) {
397                 class2type[ "[object " + name + "]" ] = name.toLowerCase();
398         } );
400 export default jQuery;