3.5.1
[jquery.git] / src / core.js
blobd43cae326f21c7cc358f655d35fc25255762860b
1 /* global Symbol */
2 // Defining this global in .eslintrc.json would create a danger of using the global
3 // unguarded in another place, it seems safer to define global only for this module
5 define( [
6         "./var/arr",
7         "./var/getProto",
8         "./var/slice",
9         "./var/flat",
10         "./var/push",
11         "./var/indexOf",
12         "./var/class2type",
13         "./var/toString",
14         "./var/hasOwn",
15         "./var/fnToString",
16         "./var/ObjectFunctionString",
17         "./var/support",
18         "./var/isFunction",
19         "./var/isWindow",
20         "./core/DOMEval",
21         "./core/toType"
22 ], function( arr, getProto, slice, flat, push, indexOf,
23         class2type, toString, hasOwn, fnToString, ObjectFunctionString,
24         support, isFunction, isWindow, DOMEval, toType ) {
26 "use strict";
28 var
29         version = "3.5.1",
31         // Define a local copy of jQuery
32         jQuery = function( selector, context ) {
34                 // The jQuery object is actually just the init constructor 'enhanced'
35                 // Need init if jQuery is called (just allow error to be thrown if not included)
36                 return new jQuery.fn.init( selector, context );
37         };
39 jQuery.fn = jQuery.prototype = {
41         // The current version of jQuery being used
42         jquery: version,
44         constructor: jQuery,
46         // The default length of a jQuery object is 0
47         length: 0,
49         toArray: function() {
50                 return slice.call( this );
51         },
53         // Get the Nth element in the matched element set OR
54         // Get the whole matched element set as a clean array
55         get: function( num ) {
57                 // Return all the elements in a clean array
58                 if ( num == null ) {
59                         return slice.call( this );
60                 }
62                 // Return just the one element from the set
63                 return num < 0 ? this[ num + this.length ] : this[ num ];
64         },
66         // Take an array of elements and push it onto the stack
67         // (returning the new matched element set)
68         pushStack: function( elems ) {
70                 // Build a new jQuery matched element set
71                 var ret = jQuery.merge( this.constructor(), elems );
73                 // Add the old object onto the stack (as a reference)
74                 ret.prevObject = this;
76                 // Return the newly-formed element set
77                 return ret;
78         },
80         // Execute a callback for every element in the matched set.
81         each: function( callback ) {
82                 return jQuery.each( this, callback );
83         },
85         map: function( callback ) {
86                 return this.pushStack( jQuery.map( this, function( elem, i ) {
87                         return callback.call( elem, i, elem );
88                 } ) );
89         },
91         slice: function() {
92                 return this.pushStack( slice.apply( this, arguments ) );
93         },
95         first: function() {
96                 return this.eq( 0 );
97         },
99         last: function() {
100                 return this.eq( -1 );
101         },
103         even: function() {
104                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
105                         return ( i + 1 ) % 2;
106                 } ) );
107         },
109         odd: function() {
110                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
111                         return i % 2;
112                 } ) );
113         },
115         eq: function( i ) {
116                 var len = this.length,
117                         j = +i + ( i < 0 ? len : 0 );
118                 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
119         },
121         end: function() {
122                 return this.prevObject || this.constructor();
123         },
125         // For internal use only.
126         // Behaves like an Array's method, not like a jQuery method.
127         push: push,
128         sort: arr.sort,
129         splice: arr.splice
132 jQuery.extend = jQuery.fn.extend = function() {
133         var options, name, src, copy, copyIsArray, clone,
134                 target = arguments[ 0 ] || {},
135                 i = 1,
136                 length = arguments.length,
137                 deep = false;
139         // Handle a deep copy situation
140         if ( typeof target === "boolean" ) {
141                 deep = target;
143                 // Skip the boolean and the target
144                 target = arguments[ i ] || {};
145                 i++;
146         }
148         // Handle case when target is a string or something (possible in deep copy)
149         if ( typeof target !== "object" && !isFunction( target ) ) {
150                 target = {};
151         }
153         // Extend jQuery itself if only one argument is passed
154         if ( i === length ) {
155                 target = this;
156                 i--;
157         }
159         for ( ; i < length; i++ ) {
161                 // Only deal with non-null/undefined values
162                 if ( ( options = arguments[ i ] ) != null ) {
164                         // Extend the base object
165                         for ( name in options ) {
166                                 copy = options[ name ];
168                                 // Prevent Object.prototype pollution
169                                 // Prevent never-ending loop
170                                 if ( name === "__proto__" || target === copy ) {
171                                         continue;
172                                 }
174                                 // Recurse if we're merging plain objects or arrays
175                                 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
176                                         ( copyIsArray = Array.isArray( copy ) ) ) ) {
177                                         src = target[ name ];
179                                         // Ensure proper type for the source value
180                                         if ( copyIsArray && !Array.isArray( src ) ) {
181                                                 clone = [];
182                                         } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
183                                                 clone = {};
184                                         } else {
185                                                 clone = src;
186                                         }
187                                         copyIsArray = false;
189                                         // Never move original objects, clone them
190                                         target[ name ] = jQuery.extend( deep, clone, copy );
192                                 // Don't bring in undefined values
193                                 } else if ( copy !== undefined ) {
194                                         target[ name ] = copy;
195                                 }
196                         }
197                 }
198         }
200         // Return the modified object
201         return target;
204 jQuery.extend( {
206         // Unique for each copy of jQuery on the page
207         expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
209         // Assume jQuery is ready without the ready module
210         isReady: true,
212         error: function( msg ) {
213                 throw new Error( msg );
214         },
216         noop: function() {},
218         isPlainObject: function( obj ) {
219                 var proto, Ctor;
221                 // Detect obvious negatives
222                 // Use toString instead of jQuery.type to catch host objects
223                 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
224                         return false;
225                 }
227                 proto = getProto( obj );
229                 // Objects with no prototype (e.g., `Object.create( null )`) are plain
230                 if ( !proto ) {
231                         return true;
232                 }
234                 // Objects with prototype are plain iff they were constructed by a global Object function
235                 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
236                 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
237         },
239         isEmptyObject: function( obj ) {
240                 var name;
242                 for ( name in obj ) {
243                         return false;
244                 }
245                 return true;
246         },
248         // Evaluates a script in a provided context; falls back to the global one
249         // if not specified.
250         globalEval: function( code, options, doc ) {
251                 DOMEval( code, { nonce: options && options.nonce }, doc );
252         },
254         each: function( obj, callback ) {
255                 var length, i = 0;
257                 if ( isArrayLike( obj ) ) {
258                         length = obj.length;
259                         for ( ; i < length; i++ ) {
260                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
261                                         break;
262                                 }
263                         }
264                 } else {
265                         for ( i in obj ) {
266                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
267                                         break;
268                                 }
269                         }
270                 }
272                 return obj;
273         },
275         // results is for internal usage only
276         makeArray: function( arr, results ) {
277                 var ret = results || [];
279                 if ( arr != null ) {
280                         if ( isArrayLike( Object( arr ) ) ) {
281                                 jQuery.merge( ret,
282                                         typeof arr === "string" ?
283                                         [ arr ] : arr
284                                 );
285                         } else {
286                                 push.call( ret, arr );
287                         }
288                 }
290                 return ret;
291         },
293         inArray: function( elem, arr, i ) {
294                 return arr == null ? -1 : indexOf.call( arr, elem, i );
295         },
297         // Support: Android <=4.0 only, PhantomJS 1 only
298         // push.apply(_, arraylike) throws on ancient WebKit
299         merge: function( first, second ) {
300                 var len = +second.length,
301                         j = 0,
302                         i = first.length;
304                 for ( ; j < len; j++ ) {
305                         first[ i++ ] = second[ j ];
306                 }
308                 first.length = i;
310                 return first;
311         },
313         grep: function( elems, callback, invert ) {
314                 var callbackInverse,
315                         matches = [],
316                         i = 0,
317                         length = elems.length,
318                         callbackExpect = !invert;
320                 // Go through the array, only saving the items
321                 // that pass the validator function
322                 for ( ; i < length; i++ ) {
323                         callbackInverse = !callback( elems[ i ], i );
324                         if ( callbackInverse !== callbackExpect ) {
325                                 matches.push( elems[ i ] );
326                         }
327                 }
329                 return matches;
330         },
332         // arg is for internal usage only
333         map: function( elems, callback, arg ) {
334                 var length, value,
335                         i = 0,
336                         ret = [];
338                 // Go through the array, translating each of the items to their new values
339                 if ( isArrayLike( elems ) ) {
340                         length = elems.length;
341                         for ( ; i < length; i++ ) {
342                                 value = callback( elems[ i ], i, arg );
344                                 if ( value != null ) {
345                                         ret.push( value );
346                                 }
347                         }
349                 // Go through every key on the object,
350                 } else {
351                         for ( i in elems ) {
352                                 value = callback( elems[ i ], i, arg );
354                                 if ( value != null ) {
355                                         ret.push( value );
356                                 }
357                         }
358                 }
360                 // Flatten any nested arrays
361                 return flat( ret );
362         },
364         // A global GUID counter for objects
365         guid: 1,
367         // jQuery.support is not used in Core but other projects attach their
368         // properties to it so it needs to exist.
369         support: support
370 } );
372 if ( typeof Symbol === "function" ) {
373         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
376 // Populate the class2type map
377 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
378 function( _i, name ) {
379         class2type[ "[object " + name + "]" ] = name.toLowerCase();
380 } );
382 function isArrayLike( obj ) {
384         // Support: real iOS 8.2 only (not reproducible in simulator)
385         // `in` check used to prevent JIT error (gh-2145)
386         // hasOwn isn't used here due to false negatives
387         // regarding Nodelist length in IE
388         var length = !!obj && "length" in obj && obj.length,
389                 type = toType( obj );
391         if ( isFunction( obj ) || isWindow( obj ) ) {
392                 return false;
393         }
395         return type === "array" || length === 0 ||
396                 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
399 return jQuery;
400 } );