X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=src%2Fcore.js;h=e1a3a6df2523b0d335cbfcf1ebe114513efbc186;hb=b3ccf2f2881d9ad988aba1cf3ccffb810063ab29;hp=3ff95e0205f5118598a1e92e5ded9296692095ab;hpb=a6ef036bb6a3610431471eebc2623bf8ad06bdd6;p=jquery.git diff --git a/src/core.js b/src/core.js index 3ff95e0..e1a3a6d 100644 --- a/src/core.js +++ b/src/core.js @@ -1,3 +1,5 @@ +(function() { + // Define a local copy of jQuery var jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' @@ -11,14 +13,14 @@ var jQuery = function( selector, context ) { _$ = window.$, // Use the correct document accordingly with window argument (sandbox) - document = window.document, + //document = window.document, // A central reference to the root jQuery(document) rootjQuery, // A simple way to check for HTML strings or ID strings // (both of which we optimize for) - quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/, + quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w\-]+)$/, // Is it a simple selector isSimple = /^.[^:#\[\.,]*$/, @@ -27,7 +29,8 @@ var jQuery = function( selector, context ) { rnotwhite = /\S/, // Used for trimming whitespace - rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g, + trimLeft = /^\s+/, + trimRight = /\s+$/, // Match a standalone tag rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/, @@ -49,9 +52,10 @@ var jQuery = function( selector, context ) { // Save a reference to some core methods toString = Object.prototype.toString, - hasOwnProperty = Object.prototype.hasOwnProperty, + hasOwn = Object.prototype.hasOwnProperty, push = Array.prototype.push, slice = Array.prototype.slice, + trim = String.prototype.trim, indexOf = Array.prototype.indexOf; jQuery.fn = jQuery.prototype = { @@ -69,6 +73,15 @@ jQuery.fn = jQuery.prototype = { this.length = 1; return this; } + + // The body element only exists once, optimize finding it + if ( selector === "body" && !context ) { + this.context = document; + this[0] = document.body; + this.selector = "body"; + this.length = 1; + return this; + } // Handle HTML strings if ( typeof selector === "string" ) { @@ -99,7 +112,9 @@ jQuery.fn = jQuery.prototype = { ret = buildFragment( [ match[1] ], [ doc ] ); selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes; } - + + return jQuery.merge( this, selector ); + // HANDLE: $("#id") } else { elem = document.getElementById( match[2] ); @@ -126,6 +141,7 @@ jQuery.fn = jQuery.prototype = { this.selector = selector; this.context = document; selector = document.getElementsByTagName( selector ); + return jQuery.merge( this, selector ); // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { @@ -148,9 +164,7 @@ jQuery.fn = jQuery.prototype = { this.context = selector.context; } - return jQuery.isArray( selector ) ? - this.setArray( selector ) : - jQuery.makeArray( selector, this ); + return jQuery.makeArray( selector, this ); }, // Start with an empty selector @@ -187,7 +201,14 @@ jQuery.fn = jQuery.prototype = { // (returning the new matched element set) pushStack: function( elems, name, selector ) { // Build a new jQuery matched element set - var ret = jQuery( elems || null ); + var ret = jQuery(); + + if ( jQuery.isArray( elems ) ) { + push.apply( ret, elems ); + + } else { + jQuery.merge( ret, elems ); + } // Add the old object onto the stack (as a reference) ret.prevObject = this; @@ -204,18 +225,6 @@ jQuery.fn = jQuery.prototype = { return ret; }, - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - push.apply( this, elems ); - - return this; - }, - // Execute a callback for every element in the matched set. // (You can seed the arguments with an array of args, but this is // only used internally.) @@ -445,9 +454,9 @@ jQuery.extend({ } // Not own constructor property must be Object - if ( obj.constructor - && !hasOwnProperty.call(obj, "constructor") - && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) { + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { return false; } @@ -457,7 +466,7 @@ jQuery.extend({ var key; for ( key in obj ) {} - return key === undefined || hasOwnProperty.call( obj, key ); + return key === undefined || hasOwn.call( obj, key ); }, isEmptyObject: function( obj ) { @@ -470,6 +479,30 @@ jQuery.extend({ error: function( msg ) { throw msg; }, + + parseJSON: function( data ) { + if ( typeof data !== "string" || !data ) { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@") + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]") + .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) { + + // Try to use the native JSON parser first + return window.JSON && window.JSON.parse ? + window.JSON.parse( data ) : + (new Function("return " + data))(); + + } else { + jQuery.error( "Invalid JSON: " + data ); + } + }, noop: function() {}, @@ -538,9 +571,20 @@ jQuery.extend({ return object; }, - trim: function( text ) { - return (text || "").replace( rtrim, "" ); - }, + // Use native String.trim function wherever possible + trim: trim ? + function( text ) { + return text == null ? + "" : + trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + text.toString().replace( trimLeft, "" ).replace( trimRight, "" ); + }, // results is for internal usage only makeArray: function( array, results ) { @@ -581,6 +625,7 @@ jQuery.extend({ for ( var l = second.length; j < l; j++ ) { first[ i++ ] = second[ j ]; } + } else { while ( second[j] !== undefined ) { first[ i++ ] = second[ j++ ]; @@ -593,12 +638,14 @@ jQuery.extend({ }, grep: function( elems, callback, inv ) { - var ret = []; + var ret = [], retVal; + inv = !!inv; // Go through the array, only saving the items // that pass the validator function for ( var i = 0, length = elems.length; i < length; i++ ) { - if ( !inv !== !callback( elems[ i ], i ) ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { ret.push( elems[ i ] ); } } @@ -654,6 +701,39 @@ jQuery.extend({ return proxy; }, + // Mutifunctional method to get and set values to a collection + // The value/s can be optionally by executed if its a function + access: function( elems, key, value, exec, fn, pass ) { + var length = elems.length; + + // Setting many attributes + if ( typeof key === "object" ) { + for ( var k in key ) { + jQuery.access( elems, k, key[k], exec, fn, value ); + } + return elems; + } + + // Setting one attribute + if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = !pass && exec && jQuery.isFunction(value); + + for ( var i = 0; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + + return elems; + } + + // Getting an attribute + return length ? fn( elems[0], key ) : undefined; + }, + + now: function() { + return (new Date()).getTime(); + }, + // Use of jQuery.browser is frowned upon. // More details: http://docs.jquery.com/Utilities/jQuery.browser uaMatch: function( ua ) { @@ -663,7 +743,7 @@ jQuery.extend({ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || /(msie) ([\w.]+)/.exec( ua ) || !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || - []; + []; return { browser: match[1] || "", version: match[2] || "0" }; }, @@ -688,6 +768,13 @@ if ( indexOf ) { }; } +// Verify that \s matches non-breaking spaces +// (IE fails on this test) +if ( !/\s/.test( "\xA0" ) ) { + trimLeft = /^[\s\xA0]+/; + trimRight = /[\s\xA0]+$/; +} + // All jQuery objects should point back to these rootjQuery = jQuery(document); @@ -718,7 +805,7 @@ function doScrollCheck() { // If IE is used, use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); - } catch( error ) { + } catch(e) { setTimeout( doScrollCheck, 1 ); return; } @@ -727,51 +814,7 @@ function doScrollCheck() { jQuery.ready(); } -function evalScript( i, elem ) { - if ( elem.src ) { - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - } else { - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - } - - if ( elem.parentNode ) { - elem.parentNode.removeChild( elem ); - } -} - -// Mutifunctional method to get and set values to a collection -// The value/s can be optionally by executed if its a function -function access( elems, key, value, exec, fn, pass ) { - var length = elems.length; - - // Setting many attributes - if ( typeof key === "object" ) { - for ( var k in key ) { - access( elems, k, key[k], exec, fn, value ); - } - return elems; - } - - // Setting one attribute - if ( value !== undefined ) { - // Optionally, function values get executed if exec is true - exec = !pass && exec && jQuery.isFunction(value); - - for ( var i = 0; i < length; i++ ) { - fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); - } - - return elems; - } - - // Getting an attribute - return length ? fn( elems[0], key ) : null; -} +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; -function now() { - return (new Date).getTime(); -} +})();