3.3.0
[jquery.git] / src / core.js
blobb2c51fa122acdcfeaf892f7125cd915448038b1d
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/document",
8         "./var/getProto",
9         "./var/slice",
10         "./var/concat",
11         "./var/push",
12         "./var/indexOf",
13         "./var/class2type",
14         "./var/toString",
15         "./var/hasOwn",
16         "./var/fnToString",
17         "./var/ObjectFunctionString",
18         "./var/support",
19         "./var/isFunction",
20         "./var/isWindow",
21         "./core/DOMEval",
22         "./core/toType"
23 ], function( arr, document, getProto, slice, concat, push, indexOf,
24         class2type, toString, hasOwn, fnToString, ObjectFunctionString,
25         support, isFunction, isWindow, DOMEval, toType ) {
27 "use strict";
29 var
30         version = "3.3.0",
32         // Define a local copy of jQuery
33         jQuery = function( selector, context ) {
35                 // The jQuery object is actually just the init constructor 'enhanced'
36                 // Need init if jQuery is called (just allow error to be thrown if not included)
37                 return new jQuery.fn.init( selector, context );
38         },
40         // Support: Android <=4.0 only
41         // Make sure we trim BOM and NBSP
42         rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
44 jQuery.fn = jQuery.prototype = {
46         // The current version of jQuery being used
47         jquery: version,
49         constructor: jQuery,
51         // The default length of a jQuery object is 0
52         length: 0,
54         toArray: function() {
55                 return slice.call( this );
56         },
58         // Get the Nth element in the matched element set OR
59         // Get the whole matched element set as a clean array
60         get: function( num ) {
62                 // Return all the elements in a clean array
63                 if ( num == null ) {
64                         return slice.call( this );
65                 }
67                 // Return just the one element from the set
68                 return num < 0 ? this[ num + this.length ] : this[ num ];
69         },
71         // Take an array of elements and push it onto the stack
72         // (returning the new matched element set)
73         pushStack: function( elems ) {
75                 // Build a new jQuery matched element set
76                 var ret = jQuery.merge( this.constructor(), elems );
78                 // Add the old object onto the stack (as a reference)
79                 ret.prevObject = this;
81                 // Return the newly-formed element set
82                 return ret;
83         },
85         // Execute a callback for every element in the matched set.
86         each: function( callback ) {
87                 return jQuery.each( this, callback );
88         },
90         map: function( callback ) {
91                 return this.pushStack( jQuery.map( this, function( elem, i ) {
92                         return callback.call( elem, i, elem );
93                 } ) );
94         },
96         slice: function() {
97                 return this.pushStack( slice.apply( this, arguments ) );
98         },
100         first: function() {
101                 return this.eq( 0 );
102         },
104         last: function() {
105                 return this.eq( -1 );
106         },
108         eq: function( i ) {
109                 var len = this.length,
110                         j = +i + ( i < 0 ? len : 0 );
111                 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
112         },
114         end: function() {
115                 return this.prevObject || this.constructor();
116         },
118         // For internal use only.
119         // Behaves like an Array's method, not like a jQuery method.
120         push: push,
121         sort: arr.sort,
122         splice: arr.splice
125 jQuery.extend = jQuery.fn.extend = function() {
126         var options, name, src, copy, copyIsArray, clone,
127                 target = arguments[ 0 ] || {},
128                 i = 1,
129                 length = arguments.length,
130                 deep = false;
132         // Handle a deep copy situation
133         if ( typeof target === "boolean" ) {
134                 deep = target;
136                 // Skip the boolean and the target
137                 target = arguments[ i ] || {};
138                 i++;
139         }
141         // Handle case when target is a string or something (possible in deep copy)
142         if ( typeof target !== "object" && !isFunction( target ) ) {
143                 target = {};
144         }
146         // Extend jQuery itself if only one argument is passed
147         if ( i === length ) {
148                 target = this;
149                 i--;
150         }
152         for ( ; i < length; i++ ) {
154                 // Only deal with non-null/undefined values
155                 if ( ( options = arguments[ i ] ) != null ) {
157                         // Extend the base object
158                         for ( name in options ) {
159                                 src = target[ name ];
160                                 copy = options[ name ];
162                                 // Prevent never-ending loop
163                                 if ( target === copy ) {
164                                         continue;
165                                 }
167                                 // Recurse if we're merging plain objects or arrays
168                                 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
169                                         ( copyIsArray = Array.isArray( copy ) ) ) ) {
171                                         if ( copyIsArray ) {
172                                                 copyIsArray = false;
173                                                 clone = src && Array.isArray( src ) ? src : [];
175                                         } else {
176                                                 clone = src && jQuery.isPlainObject( src ) ? src : {};
177                                         }
179                                         // Never move original objects, clone them
180                                         target[ name ] = jQuery.extend( deep, clone, copy );
182                                 // Don't bring in undefined values
183                                 } else if ( copy !== undefined ) {
184                                         target[ name ] = copy;
185                                 }
186                         }
187                 }
188         }
190         // Return the modified object
191         return target;
194 jQuery.extend( {
196         // Unique for each copy of jQuery on the page
197         expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
199         // Assume jQuery is ready without the ready module
200         isReady: true,
202         error: function( msg ) {
203                 throw new Error( msg );
204         },
206         noop: function() {},
208         isPlainObject: function( obj ) {
209                 var proto, Ctor;
211                 // Detect obvious negatives
212                 // Use toString instead of jQuery.type to catch host objects
213                 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
214                         return false;
215                 }
217                 proto = getProto( obj );
219                 // Objects with no prototype (e.g., `Object.create( null )`) are plain
220                 if ( !proto ) {
221                         return true;
222                 }
224                 // Objects with prototype are plain iff they were constructed by a global Object function
225                 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
226                 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
227         },
229         isEmptyObject: function( obj ) {
231                 /* eslint-disable no-unused-vars */
232                 // See https://github.com/eslint/eslint/issues/6125
233                 var name;
235                 for ( name in obj ) {
236                         return false;
237                 }
238                 return true;
239         },
241         // Evaluates a script in a global context
242         globalEval: function( code ) {
243                 DOMEval( code );
244         },
246         each: function( obj, callback ) {
247                 var length, i = 0;
249                 if ( isArrayLike( obj ) ) {
250                         length = obj.length;
251                         for ( ; i < length; i++ ) {
252                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
253                                         break;
254                                 }
255                         }
256                 } else {
257                         for ( i in obj ) {
258                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
259                                         break;
260                                 }
261                         }
262                 }
264                 return obj;
265         },
267         // Support: Android <=4.0 only
268         trim: function( text ) {
269                 return text == null ?
270                         "" :
271                         ( text + "" ).replace( rtrim, "" );
272         },
274         // results is for internal usage only
275         makeArray: function( arr, results ) {
276                 var ret = results || [];
278                 if ( arr != null ) {
279                         if ( isArrayLike( Object( arr ) ) ) {
280                                 jQuery.merge( ret,
281                                         typeof arr === "string" ?
282                                         [ arr ] : arr
283                                 );
284                         } else {
285                                 push.call( ret, arr );
286                         }
287                 }
289                 return ret;
290         },
292         inArray: function( elem, arr, i ) {
293                 return arr == null ? -1 : indexOf.call( arr, elem, i );
294         },
296         // Support: Android <=4.0 only, PhantomJS 1 only
297         // push.apply(_, arraylike) throws on ancient WebKit
298         merge: function( first, second ) {
299                 var len = +second.length,
300                         j = 0,
301                         i = first.length;
303                 for ( ; j < len; j++ ) {
304                         first[ i++ ] = second[ j ];
305                 }
307                 first.length = i;
309                 return first;
310         },
312         grep: function( elems, callback, invert ) {
313                 var callbackInverse,
314                         matches = [],
315                         i = 0,
316                         length = elems.length,
317                         callbackExpect = !invert;
319                 // Go through the array, only saving the items
320                 // that pass the validator function
321                 for ( ; i < length; i++ ) {
322                         callbackInverse = !callback( elems[ i ], i );
323                         if ( callbackInverse !== callbackExpect ) {
324                                 matches.push( elems[ i ] );
325                         }
326                 }
328                 return matches;
329         },
331         // arg is for internal usage only
332         map: function( elems, callback, arg ) {
333                 var length, value,
334                         i = 0,
335                         ret = [];
337                 // Go through the array, translating each of the items to their new values
338                 if ( isArrayLike( elems ) ) {
339                         length = elems.length;
340                         for ( ; i < length; i++ ) {
341                                 value = callback( elems[ i ], i, arg );
343                                 if ( value != null ) {
344                                         ret.push( value );
345                                 }
346                         }
348                 // Go through every key on the object,
349                 } else {
350                         for ( i in elems ) {
351                                 value = callback( elems[ i ], i, arg );
353                                 if ( value != null ) {
354                                         ret.push( value );
355                                 }
356                         }
357                 }
359                 // Flatten any nested arrays
360                 return concat.apply( [], ret );
361         },
363         // A global GUID counter for objects
364         guid: 1,
366         // jQuery.support is not used in Core but other projects attach their
367         // properties to it so it needs to exist.
368         support: support
369 } );
371 if ( typeof Symbol === "function" ) {
372         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
375 // Populate the class2type map
376 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
377 function( i, name ) {
378         class2type[ "[object " + name + "]" ] = name.toLowerCase();
379 } );
381 function isArrayLike( obj ) {
383         // Support: real iOS 8.2 only (not reproducible in simulator)
384         // `in` check used to prevent JIT error (gh-2145)
385         // hasOwn isn't used here due to false negatives
386         // regarding Nodelist length in IE
387         var length = !!obj && "length" in obj && obj.length,
388                 type = toType( obj );
390         if ( isFunction( obj ) || isWindow( obj ) ) {
391                 return false;
392         }
394         return type === "array" || length === 0 ||
395                 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
398 return jQuery;
399 } );