Manipulation: execute scripts from iframe in the iframe's context
[jquery.git] / src / core.js
blob9095213eb3b7b08722df28ef4f5da5feba74dabf
1 define( [
2         "./var/arr",
3         "./var/document",
4         "./var/slice",
5         "./var/concat",
6         "./var/push",
7         "./var/indexOf",
8         "./var/class2type",
9         "./var/toString",
10         "./var/hasOwn",
11         "./var/support"
12 ], function( arr, document, slice, concat, push, indexOf, class2type, toString, hasOwn, support ) {
14 var
15         version = "@VERSION",
17         // Define a local copy of jQuery
18         jQuery = function( selector, context ) {
20                 // The jQuery object is actually just the init constructor 'enhanced'
21                 // Need init if jQuery is called (just allow error to be thrown if not included)
22                 return new jQuery.fn.init( selector, context );
23         },
25         // Support: Android<4.1
26         // Make sure we trim BOM and NBSP
27         rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
29         // Matches dashed string for camelizing
30         rmsPrefix = /^-ms-/,
31         rdashAlpha = /-([a-z])/g,
33         // Used by jQuery.camelCase as callback to replace()
34         fcamelCase = function( all, letter ) {
35                 return letter.toUpperCase();
36         };
38 jQuery.fn = jQuery.prototype = {
40         // The current version of jQuery being used
41         jquery: version,
43         constructor: jQuery,
45         // The default length of a jQuery object is 0
46         length: 0,
48         toArray: function() {
49                 return slice.call( this );
50         },
52         // Get the Nth element in the matched element set OR
53         // Get the whole matched element set as a clean array
54         get: function( num ) {
55                 return num != null ?
57                         // Return just the one element from the set
58                         ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
60                         // Return all the elements in a clean array
61                         slice.call( this );
62         },
64         // Take an array of elements and push it onto the stack
65         // (returning the new matched element set)
66         pushStack: function( elems ) {
68                 // Build a new jQuery matched element set
69                 var ret = jQuery.merge( this.constructor(), elems );
71                 // Add the old object onto the stack (as a reference)
72                 ret.prevObject = this;
74                 // Return the newly-formed element set
75                 return ret;
76         },
78         // Execute a callback for every element in the matched set.
79         each: function( callback ) {
80                 return jQuery.each( this, callback );
81         },
83         map: function( callback ) {
84                 return this.pushStack( jQuery.map( this, function( elem, i ) {
85                         return callback.call( elem, i, elem );
86                 } ) );
87         },
89         slice: function() {
90                 return this.pushStack( slice.apply( this, arguments ) );
91         },
93         first: function() {
94                 return this.eq( 0 );
95         },
97         last: function() {
98                 return this.eq( -1 );
99         },
101         eq: function( i ) {
102                 var len = this.length,
103                         j = +i + ( i < 0 ? len : 0 );
104                 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
105         },
107         end: function() {
108                 return this.prevObject || this.constructor();
109         },
111         // For internal use only.
112         // Behaves like an Array's method, not like a jQuery method.
113         push: push,
114         sort: arr.sort,
115         splice: arr.splice
118 jQuery.extend = jQuery.fn.extend = function() {
119         var options, name, src, copy, copyIsArray, clone,
120                 target = arguments[ 0 ] || {},
121                 i = 1,
122                 length = arguments.length,
123                 deep = false;
125         // Handle a deep copy situation
126         if ( typeof target === "boolean" ) {
127                 deep = target;
129                 // Skip the boolean and the target
130                 target = arguments[ i ] || {};
131                 i++;
132         }
134         // Handle case when target is a string or something (possible in deep copy)
135         if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
136                 target = {};
137         }
139         // Extend jQuery itself if only one argument is passed
140         if ( i === length ) {
141                 target = this;
142                 i--;
143         }
145         for ( ; i < length; i++ ) {
147                 // Only deal with non-null/undefined values
148                 if ( ( options = arguments[ i ] ) != null ) {
150                         // Extend the base object
151                         for ( name in options ) {
152                                 src = target[ name ];
153                                 copy = options[ name ];
155                                 // Prevent never-ending loop
156                                 if ( target === copy ) {
157                                         continue;
158                                 }
160                                 // Recurse if we're merging plain objects or arrays
161                                 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
162                                         ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
164                                         if ( copyIsArray ) {
165                                                 copyIsArray = false;
166                                                 clone = src && jQuery.isArray( src ) ? src : [];
168                                         } else {
169                                                 clone = src && jQuery.isPlainObject( src ) ? src : {};
170                                         }
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         isFunction: function( obj ) {
202                 return jQuery.type( obj ) === "function";
203         },
205         isArray: Array.isArray,
207         isWindow: function( obj ) {
208                 return obj != null && obj === obj.window;
209         },
211         isNumeric: function( obj ) {
213                 // As of jQuery 3.0, isNumeric is limited to
214                 // strings and numbers (primitives or objects)
215                 // that can be coerced to finite numbers (gh-2662)
216                 var type = jQuery.type( obj );
217                 return ( type === "number" || type === "string" ) &&
218                         ( obj - parseFloat( obj ) + 1 ) >= 0;
219         },
221         isPlainObject: function( obj ) {
223                 // Not plain objects:
224                 // - Any object or value whose internal [[Class]] property is not "[object Object]"
225                 // - DOM nodes
226                 // - window
227                 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
228                         return false;
229                 }
231                 if ( obj.constructor &&
232                                 !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
233                         return false;
234                 }
236                 // If the function hasn't returned already, we're confident that
237                 // |obj| is a plain object, created by {} or constructed with new Object
238                 return true;
239         },
241         isEmptyObject: function( obj ) {
242                 var name;
243                 for ( name in obj ) {
244                         return false;
245                 }
246                 return true;
247         },
249         type: function( obj ) {
250                 if ( obj == null ) {
251                         return obj + "";
252                 }
254                 // Support: Android<4.0 (functionish RegExp)
255                 return typeof obj === "object" || typeof obj === "function" ?
256                         class2type[ toString.call( obj ) ] || "object" :
257                         typeof obj;
258         },
260         // Evaluates a script in a global context
261         globalEval: function( code, context ) {
262                 context = context || document;
263                 var script = context.createElement( "script" );
265                 script.text = code;
266                 context.head.appendChild( script ).parentNode.removeChild( script );
267         },
269         // Convert dashed to camelCase; used by the css and data modules
270         // Support: IE9-11+
271         // Microsoft forgot to hump their vendor prefix (#9572)
272         camelCase: function( string ) {
273                 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
274         },
276         nodeName: function( elem, name ) {
277                 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
278         },
280         each: function( obj, callback ) {
281                 var length, i = 0;
283                 if ( isArrayLike( obj ) ) {
284                         length = obj.length;
285                         for ( ; i < length; i++ ) {
286                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
287                                         break;
288                                 }
289                         }
290                 } else {
291                         for ( i in obj ) {
292                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
293                                         break;
294                                 }
295                         }
296                 }
298                 return obj;
299         },
301         // Support: Android<4.1
302         trim: function( text ) {
303                 return text == null ?
304                         "" :
305                         ( text + "" ).replace( rtrim, "" );
306         },
308         // results is for internal usage only
309         makeArray: function( arr, results ) {
310                 var ret = results || [];
312                 if ( arr != null ) {
313                         if ( isArrayLike( Object( arr ) ) ) {
314                                 jQuery.merge( ret,
315                                         typeof arr === "string" ?
316                                         [ arr ] : arr
317                                 );
318                         } else {
319                                 push.call( ret, arr );
320                         }
321                 }
323                 return ret;
324         },
326         inArray: function( elem, arr, i ) {
327                 return arr == null ? -1 : indexOf.call( arr, elem, i );
328         },
330         // Support: Android<4.1, PhantomJS<2
331         // push.apply(_, arraylike) throws on ancient WebKit
332         merge: function( first, second ) {
333                 var len = +second.length,
334                         j = 0,
335                         i = first.length;
337                 for ( ; j < len; j++ ) {
338                         first[ i++ ] = second[ j ];
339                 }
341                 first.length = i;
343                 return first;
344         },
346         grep: function( elems, callback, invert ) {
347                 var callbackInverse,
348                         matches = [],
349                         i = 0,
350                         length = elems.length,
351                         callbackExpect = !invert;
353                 // Go through the array, only saving the items
354                 // that pass the validator function
355                 for ( ; i < length; i++ ) {
356                         callbackInverse = !callback( elems[ i ], i );
357                         if ( callbackInverse !== callbackExpect ) {
358                                 matches.push( elems[ i ] );
359                         }
360                 }
362                 return matches;
363         },
365         // arg is for internal usage only
366         map: function( elems, callback, arg ) {
367                 var length, value,
368                         i = 0,
369                         ret = [];
371                 // Go through the array, translating each of the items to their new values
372                 if ( isArrayLike( elems ) ) {
373                         length = elems.length;
374                         for ( ; i < length; i++ ) {
375                                 value = callback( elems[ i ], i, arg );
377                                 if ( value != null ) {
378                                         ret.push( value );
379                                 }
380                         }
382                 // Go through every key on the object,
383                 } else {
384                         for ( i in elems ) {
385                                 value = callback( elems[ i ], i, arg );
387                                 if ( value != null ) {
388                                         ret.push( value );
389                                 }
390                         }
391                 }
393                 // Flatten any nested arrays
394                 return concat.apply( [], ret );
395         },
397         // A global GUID counter for objects
398         guid: 1,
400         // Bind a function to a context, optionally partially applying any
401         // arguments.
402         proxy: function( fn, context ) {
403                 var tmp, args, proxy;
405                 if ( typeof context === "string" ) {
406                         tmp = fn[ context ];
407                         context = fn;
408                         fn = tmp;
409                 }
411                 // Quick check to determine if target is callable, in the spec
412                 // this throws a TypeError, but we will just return undefined.
413                 if ( !jQuery.isFunction( fn ) ) {
414                         return undefined;
415                 }
417                 // Simulated bind
418                 args = slice.call( arguments, 2 );
419                 proxy = function() {
420                         return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
421                 };
423                 // Set the guid of unique handler to the same of original handler, so it can be removed
424                 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
426                 return proxy;
427         },
429         now: Date.now,
431         // jQuery.support is not used in Core but other projects attach their
432         // properties to it so it needs to exist.
433         support: support
434 } );
436 // JSHint would error on this code due to the Symbol not being defined in ES5.
437 // Defining this global in .jshintrc would create a danger of using the global
438 // unguarded in another place, it seems safer to just disable JSHint for these
439 // three lines.
440 /* jshint ignore: start */
441 if ( typeof Symbol === "function" ) {
442         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
444 /* jshint ignore: end */
446 // Populate the class2type map
447 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
448 function( i, name ) {
449         class2type[ "[object " + name + "]" ] = name.toLowerCase();
450 } );
452 function isArrayLike( obj ) {
454         // Support: iOS 8.2 (not reproducible in simulator)
455         // `in` check used to prevent JIT error (gh-2145)
456         // hasOwn isn't used here due to false negatives
457         // regarding Nodelist length in IE
458         var length = !!obj && "length" in obj && obj.length,
459                 type = jQuery.type( obj );
461         if ( type === "function" || jQuery.isWindow( obj ) ) {
462                 return false;
463         }
465         return type === "array" || length === 0 ||
466                 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
469 return jQuery;
470 } );