Build: replace CRLF with LF during minify
[jquery.git] / src / core.js
blob8ed56b7e803e9d5212e2d795c587578a3ad980cb
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 );
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 );
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 );
51 // Return just the one element from the set
52 return num < 0 ? this[ num + this.length ] : this[ num ];
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;
69 // Execute a callback for every element in the matched set.
70 each: function( callback ) {
71 return jQuery.each( this, callback );
74 map: function( callback ) {
75 return this.pushStack( jQuery.map( this, function( elem, i ) {
76 return callback.call( elem, i, elem );
77 } ) );
80 slice: function() {
81 return this.pushStack( slice.apply( this, arguments ) );
84 first: function() {
85 return this.eq( 0 );
88 last: function() {
89 return this.eq( -1 );
92 even: function() {
93 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
94 return ( i + 1 ) % 2;
95 } ) );
98 odd: function() {
99 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
100 return i % 2;
101 } ) );
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 ] ] : [] );
110 end: function() {
111 return this.prevObject || this.constructor();
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++;
131 // Handle case when target is a string or something (possible in deep copy)
132 if ( typeof target !== "object" && typeof target !== "function" ) {
133 target = {};
136 // Extend jQuery itself if only one argument is passed
137 if ( i === length ) {
138 target = this;
139 i--;
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;
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;
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;
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 );
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;
210 proto = getProto( obj );
212 // Objects with no prototype (e.g., `Object.create( null )`) are plain
213 if ( !proto ) {
214 return true;
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;
222 isEmptyObject: function( obj ) {
223 var name;
225 for ( name in obj ) {
226 return false;
228 return true;
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 );
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;
247 } else {
248 for ( i in obj ) {
249 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
250 break;
255 return obj;
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 );
275 if ( nodeType === 1 || nodeType === 11 ) {
276 return elem.textContent;
278 if ( nodeType === 9 ) {
279 return elem.documentElement.textContent;
281 if ( nodeType === 3 || nodeType === 4 ) {
282 return elem.nodeValue;
285 // Do not include comment or processing instruction nodes
287 return ret;
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
301 } else {
302 push.call( ret, arr );
306 return ret;
309 inArray: function( elem, arr, i ) {
310 return arr == null ? -1 : indexOf.call( arr, elem, i );
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" );
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 ) );
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 ];
345 first.length = i;
347 return first;
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 ] );
366 return matches;
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 );
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 );
397 // Flatten any nested arrays
398 return flat( ret );
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 default jQuery;