Merge SlexAxton/jquery:master into jquery/jquery:master.
authorColin Snover <github.com@zetafleet.com>
Mon, 27 Dec 2010 04:08:41 +0000 (22:08 -0600)
committerColin Snover <github.com@zetafleet.com>
Mon, 27 Dec 2010 04:12:56 +0000 (22:12 -0600)
43 files changed:
.gitattributes
Makefile
Rakefile
build.xml
build/google-compiler-20091218.jar [deleted file]
build/google-compiler-20100917.jar [new file with mode: 0644]
build/jslint-check.js
src/ajax.js
src/attributes.js
src/core.js
src/css.js
src/data.js
src/dimensions.js
src/effects.js
src/event.js
src/manipulation.js
src/offset.js
src/queue.js
src/support.js
src/transports/jsonp.js [new file with mode: 0644]
src/transports/script.js [new file with mode: 0644]
src/transports/xhr.js [new file with mode: 0644]
src/traversing.js
src/xhr.js [new file with mode: 0644]
test/data/atom+xml.php [new file with mode: 0644]
test/data/css.php [new file with mode: 0644]
test/data/headers.php [new file with mode: 0644]
test/data/text.php
test/data/with_fries_over_jsonp.php [new file with mode: 0644]
test/delegatetest.html
test/index.html
test/unit/ajax.js
test/unit/attributes.js
test/unit/core.js
test/unit/css.js
test/unit/data.js
test/unit/dimensions.js
test/unit/effects.js
test/unit/event.js
test/unit/manipulation.js
test/unit/selector.js
test/unit/traversing.js
version.txt

index bcb36db..d6dc470 100644 (file)
@@ -1 +1,2 @@
-* crlf=input
+*     eol=lf
+*.jar binary
index a236ed0..935f69c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ DIST_DIR = ${PREFIX}/dist
 
 RHINO ?= java -jar ${BUILD_DIR}/js.jar
 
-CLOSURE_COMPILER = ${BUILD_DIR}/google-compiler-20091218.jar
+CLOSURE_COMPILER = ${BUILD_DIR}/google-compiler-20100917.jar
 
 MINJAR ?= java -jar ${CLOSURE_COMPILER}
 
@@ -24,6 +24,10 @@ BASE_FILES = ${SRC_DIR}/core.js\
        ${SRC_DIR}/manipulation.js\
        ${SRC_DIR}/css.js\
        ${SRC_DIR}/ajax.js\
+       ${SRC_DIR}/xhr.js\
+       ${SRC_DIR}/transports/jsonp.js\
+       ${SRC_DIR}/transports/script.js\
+       ${SRC_DIR}/transports/xhr.js\
        ${SRC_DIR}/effects.js\
        ${SRC_DIR}/offset.js\
        ${SRC_DIR}/dimensions.js
@@ -39,7 +43,7 @@ SIZZLE_DIR = ${SRC_DIR}/sizzle
 QUNIT_DIR = ${TEST_DIR}/qunit
 
 JQ_VER = $(shell cat version.txt)
-VER = sed s/@VERSION/${JQ_VER}/
+VER = sed "s/@VERSION/${JQ_VER}/"
 
 DATE=$(shell git log -1 --pretty=format:%ad)
 
index 38406bd..5ea143b 100644 (file)
--- a/Rakefile
+++ b/Rakefile
@@ -9,7 +9,7 @@ test_dir  = File.join( prefix, 'test' )
 # setting DIST_DIR before calling rake
 dist_dir  = ENV['DIST_DIR'] || File.join( prefix, 'dist' )
 
-base_files = %w{intro core support data queue attributes event selector traversing manipulation css ajax effects offset dimensions outro}.map { |js| File.join( src_dir, "#{js}.js" ) }
+base_files = %w{intro core support data queue attributes event selector traversing manipulation css ajax xhr transports/jsonp transports/script transports/xhr effects offset dimensions outro}.map { |js| File.join( src_dir, "#{js}.js" ) }
 
 # Sizzle, QUnit and jQuery files/dirs
 sizzle_dir = File.join( src_dir, "sizzle" )
@@ -28,7 +28,7 @@ version    = File.read( File.join( prefix, 'version.txt' ) ).strip
 
 # Build tools
 rhino      = "java -jar #{build_dir}/js.jar"
-minfier    = "java -jar #{build_dir}/google-compiler-20091218.jar"
+minfier    = "java -jar #{build_dir}/google-compiler-20100917.jar"
 
 # Turn off output other than needed from `sh` and file commands
 verbose(false) 
@@ -135,4 +135,4 @@ def cat( files )
   files.map do |file|
     File.read(file)
   end.join('')
-end
\ No newline at end of file
+end
index e91cdd1..f6650f4 100644 (file)
--- a/build.xml
+++ b/build.xml
                        <fileset file="src/manipulation.js" />
                        <fileset file="src/css.js" />
                        <fileset file="src/ajax.js" />
+                       <fileset file="src/xhr.js" />
+                       <fileset file="src/transports/jsonp.js" />
+                       <fileset file="src/transports/script.js" />
+                       <fileset file="src/transports/xhr.js" />
                        <fileset file="src/effects.js" />
                        <fileset file="src/offset.js" />
                        <fileset file="src/dimensions.js" />
@@ -72,6 +76,7 @@
                <exec executable="git" outputproperty="date">
                        <arg line="log -1 --pretty=format:%ad" />
                </exec>
+               <replaceregexp match="(\(\s*function\s*\(\s*jQuery\s*\)\s*\{)|(\}\s*\)\s*\(\s*jQuery\s*\)\s*;)" flags="g" replace="" file="${JQ}" />
                <replaceregexp match="Date: " replace="Date: ${date}" file="${JQ}" />
                <echo message="${JQ} built." />
        </target>
@@ -89,7 +94,7 @@
                                <include name="jquery.js" />
                        </fileset>
                        <arg line="-jar" />
-                       <arg path="build/google-compiler-20091218.jar" />
+                       <arg path="build/google-compiler-20100917.jar" />
                        <arg value="--warning_level" />
                        <arg value="QUIET" />
                        <arg value="--js_output_file" />
diff --git a/build/google-compiler-20091218.jar b/build/google-compiler-20091218.jar
deleted file mode 100644 (file)
index da053a7..0000000
Binary files a/build/google-compiler-20091218.jar and /dev/null differ
diff --git a/build/google-compiler-20100917.jar b/build/google-compiler-20100917.jar
new file mode 100644 (file)
index 0000000..4dfa5ad
Binary files /dev/null and b/build/google-compiler-20100917.jar differ
index e76abc0..976975a 100644 (file)
@@ -12,8 +12,8 @@ var ok = {
        "Use '===' to compare with 'null'.": true,
        "Use '!==' to compare with 'null'.": true,
        "Expected an assignment or function call and instead saw an expression.": true,
-       "Expected a 'break' statement before 'case'.": true
-
+       "Expected a 'break' statement before 'case'.": true,
+       "'e' is already defined.": true
 };
 
 var e = JSLINT.errors, found = 0, w;
index bd9fb45..18ea203 100644 (file)
@@ -1,17 +1,11 @@
 (function( jQuery ) {
-
-var jsc = jQuery.now(),
-       rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+       
+var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
        rselectTextarea = /^(?:select|textarea)/i,
        rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
-       rnoContent = /^(?:GET|HEAD|DELETE)$/,
        rbracket = /\[\]$/,
-       jsre = /\=\?(&|$)/,
        rquery = /\?/,
-       rts = /([?&])_=[^&]*/,
-       rurl = /^(\w+:)?\/\/([^\/?#]+)/,
        r20 = /%20/g,
-       rhash = /#.*$/,
 
        // Keep a copy of the old load method
        _load = jQuery.fn.load;
@@ -49,9 +43,9 @@ jQuery.fn.extend({
                                type = "POST";
                        }
                }
-
+               
                var self = this;
-
+               
                // Request the remote document
                jQuery.ajax({
                        url: url,
@@ -90,37 +84,37 @@ jQuery.fn.extend({
        },
 
        serializeArray: function() {
-               return this.map(function() {
+               return this.map(function(){
                        return this.elements ? jQuery.makeArray(this.elements) : this;
                })
-               .filter(function() {
+               .filter(function(){
                        return this.name && !this.disabled &&
                                (this.checked || rselectTextarea.test(this.nodeName) ||
                                        rinput.test(this.type));
                })
-               .map(function( i, elem ) {
+               .map(function(i, elem){
                        var val = jQuery(this).val();
 
                        return val == null ?
                                null :
                                jQuery.isArray(val) ?
-                                       jQuery.map( val, function( val, i ) {
-                                               return { name: elem.name, value: val };
+                                       jQuery.map( val, function(val, i){
+                                               return {name: elem.name, value: val};
                                        }) :
-                                       { name: elem.name, value: val };
+                                       {name: elem.name, value: val};
                }).get();
        }
 });
 
 // Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
-       jQuery.fn[o] = function( f ) {
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function(i,o){
+       jQuery.fn[o] = function(f){
                return this.bind(o, f);
        };
 });
 
-jQuery.extend({
-       get: function( url, data, callback, type ) {
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
                // shift arguments if data argument was omited
                if ( jQuery.isFunction( data ) ) {
                        type = type || callback;
@@ -129,13 +123,16 @@ jQuery.extend({
                }
 
                return jQuery.ajax({
-                       type: "GET",
+                       type: method,
                        url: url,
                        data: data,
                        success: callback,
                        dataType: type
                });
-       },
+       };
+});
+
+jQuery.extend({
 
        getScript: function( url, callback ) {
                return jQuery.get(url, null, callback, "script");
@@ -145,23 +142,6 @@ jQuery.extend({
                return jQuery.get(url, data, callback, "json");
        },
 
-       post: function( url, data, callback, type ) {
-               // shift arguments if data argument was omited
-               if ( jQuery.isFunction( data ) ) {
-                       type = type || callback;
-                       callback = data;
-                       data = {};
-               }
-
-               return jQuery.ajax({
-                       type: "POST",
-                       url: url,
-                       data: data,
-                       success: callback,
-                       dataType: type
-               });
-       },
-
        ajaxSetup: function( settings ) {
                jQuery.extend( jQuery.ajaxSettings, settings );
        },
@@ -176,341 +156,131 @@ jQuery.extend({
                /*
                timeout: 0,
                data: null,
+               dataType: null,
+               dataTypes: null,
                username: null,
                password: null,
+               cache: null,
                traditional: false,
                */
-               // This function can be overriden by calling jQuery.ajaxSetup
                xhr: function() {
                        return new window.XMLHttpRequest();
                },
+               xhrResponseFields: {
+                       xml: "XML",
+                       text: "Text",
+                       json: "JSON"
+               },
+                       
                accepts: {
                        xml: "application/xml, text/xml",
                        html: "text/html",
-                       script: "text/javascript, application/javascript",
-                       json: "application/json, text/javascript",
                        text: "text/plain",
-                       _default: "*/*"
-               }
-       },
-
-       ajax: function( origSettings ) {
-               var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
-                       jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
-
-               s.url = s.url.replace( rhash, "" );
-
-               // Use original (not extended) context object if it was provided
-               s.context = origSettings && origSettings.context != null ? origSettings.context : s;
-
-               // convert data if not already a string
-               if ( s.data && s.processData && typeof s.data !== "string" ) {
-                       s.data = jQuery.param( s.data, s.traditional );
-               }
-
-               // Handle JSONP Parameter Callbacks
-               if ( s.dataType === "jsonp" ) {
-                       if ( type === "GET" ) {
-                               if ( !jsre.test( s.url ) ) {
-                                       s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
-                               }
-                       } else if ( !s.data || !jsre.test(s.data) ) {
-                               s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
-                       }
-                       s.dataType = "json";
-               }
-
-               // Build temporary JSONP function
-               if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
-                       jsonp = s.jsonpCallback || ("jsonp" + jsc++);
-
-                       // Replace the =? sequence both in the query string and the data
-                       if ( s.data ) {
-                               s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
-                       }
-
-                       s.url = s.url.replace(jsre, "=" + jsonp + "$1");
-
-                       // We need to make sure
-                       // that a JSONP style response is executed properly
-                       s.dataType = "script";
-
-                       // Handle JSONP-style loading
-                       var customJsonp = window[ jsonp ];
-
-                       window[ jsonp ] = function( tmp ) {
-                               data = tmp;
-                               jQuery.ajax.handleSuccess( s, xhr, status, data );
-                               jQuery.ajax.handleComplete( s, xhr, status, data );
-                               
-                               if ( jQuery.isFunction( customJsonp ) ) {
-                                       customJsonp( tmp );
-
-                               } else {
-                                       // Garbage collect
-                                       window[ jsonp ] = undefined;
-
-                                       try {
-                                               delete window[ jsonp ];
-                                       } catch( jsonpError ) {}
+                       json: "application/json, text/javascript",
+                       "*": "*/*"
+               },
+               
+               autoDataType: {
+                       xml: /xml/,
+                       html: /html/,
+                       json: /json/
+               },
+               
+               // Prefilters
+               // 1) They are useful to introduce custom dataTypes (see transport/jsonp for an example)
+               // 2) These are called:
+               //    * BEFORE asking for a transport
+               //    * AFTER param serialization (s.data is a string if s.processData is true)
+               // 3) They MUST be order agnostic
+               prefilters: [],
+               
+               // Transports bindings
+               // 1) key is the dataType
+               // 2) the catchall symbol "*" can be used
+               // 3) selection will start with transport dataType and THEN go to "*" if needed
+               transports: {
+               },
+               
+               // Checkers
+               // 1) key is dataType
+               // 2) they are called to control successful response
+               // 3) error throws is used as error data
+               dataCheckers: {
+       
+                       // Check if data is a string
+                       "text": function(data) {
+                               if ( typeof data != "string" ) {
+                                       jQuery.error("typeerror");
                                }
-                               
-                               if ( head ) {
-                                       head.removeChild( script );
+                       },
+       
+                       // Check if xml has been properly parsed
+                       "xml": function(data) {
+                               var documentElement = data ? data.documentElement : data;
+                               if ( ! documentElement || ! documentElement.nodeName ) {
+                                       jQuery.error("typeerror");
                                }
-                       };
-               }
-
-               if ( s.dataType === "script" && s.cache === null ) {
-                       s.cache = false;
-               }
-
-               if ( s.cache === false && type === "GET" ) {
-                       var ts = jQuery.now();
-
-                       // try replacing _= if it is there
-                       var ret = s.url.replace(rts, "$1_=" + ts);
-
-                       // if nothing was replaced, add timestamp to the end
-                       s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
-               }
-
-               // If data is available, append data to url for get requests
-               if ( s.data && type === "GET" ) {
-                       s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
-               }
-
-               // Watch for a new set of requests
-               if ( s.global && jQuery.ajax.active++ === 0 ) {
-                       jQuery.event.trigger( "ajaxStart" );
-               }
-
-               // Matches an absolute URL, and saves the domain
-               var parts = rurl.exec( s.url ),
-                       remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);
-
-               // If we're requesting a remote document
-               // and trying to load JSON or Script with a GET
-               if ( s.dataType === "script" && type === "GET" && remote ) {
-                       var head = document.getElementsByTagName("head")[0] || document.documentElement;
-                       var script = document.createElement("script");
-                       if ( s.scriptCharset ) {
-                               script.charset = s.scriptCharset;
-                       }
-                       script.src = s.url;
-
-                       // Handle Script loading
-                       if ( !jsonp ) {
-                               var done = false;
-
-                               // Attach handlers for all browsers
-                               script.onload = script.onreadystatechange = function() {
-                                       if ( !done && (!this.readyState ||
-                                                       this.readyState === "loaded" || this.readyState === "complete") ) {
-                                               done = true;
-                                               jQuery.ajax.handleSuccess( s, xhr, status, data );
-                                               jQuery.ajax.handleComplete( s, xhr, status, data );
-
-                                               // Handle memory leak in IE
-                                               script.onload = script.onreadystatechange = null;
-                                               if ( head && script.parentNode ) {
-                                                       head.removeChild( script );
-                                               }
-                                       }
-                               };
-                       }
-
-                       // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
-                       // This arises when a base node is used (#2709 and #4378).
-                       head.insertBefore( script, head.firstChild );
-
-                       // We handle everything using the script element injection
-                       return undefined;
-               }
-
-               var requestDone = false;
-
-               // Create the request object
-               var xhr = s.xhr();
-
-               if ( !xhr ) {
-                       return;
-               }
-
-               // Open the socket
-               // Passing null username, generates a login popup on Opera (#2865)
-               if ( s.username ) {
-                       xhr.open(type, s.url, s.async, s.username, s.password);
-               } else {
-                       xhr.open(type, s.url, s.async);
-               }
-
-               // Need an extra try/catch for cross domain requests in Firefox 3
-               try {
-                       // Set content-type if data specified and content-body is valid for this type
-                       if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
-                               xhr.setRequestHeader("Content-Type", s.contentType);
-                       }
-
-                       // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
-                       if ( s.ifModified ) {
-                               if ( jQuery.lastModified[s.url] ) {
-                                       xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
-                               }
-
-                               if ( jQuery.ajax.etag[s.url] ) {
-                                       xhr.setRequestHeader("If-None-Match", jQuery.ajax.etag[s.url]);
+                               if ( documentElement.nodeName == "parsererror" ) {
+                                       jQuery.error("parsererror");
                                }
                        }
-
-                       // Set header so the called script knows that it's an XMLHttpRequest
-                       // Only send the header if it's not a remote XHR
-                       if ( !remote ) {
-                               xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-                       }
-
-                       // Set the Accepts header for the server, depending on the dataType
-                       xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
-                               s.accepts[ s.dataType ] + ", */*; q=0.01" :
-                               s.accepts._default );
-               } catch( headerError ) {}
-
-               // Allow custom headers/mimetypes and early abort
-               if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
-                       // Handle the global AJAX counter
-                       if ( s.global && jQuery.ajax.active-- === 1 ) {
-                               jQuery.event.trigger( "ajaxStop" );
-                       }
-
-                       // close opended socket
-                       xhr.abort();
-                       return false;
-               }
-
-               if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxSend", [xhr, s] );
-               }
-
-               // Wait for a response to come back
-               var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
-                       // The request was aborted
-                       if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
-                               // Opera doesn't call onreadystatechange before this point
-                               // so we simulate the call
-                               if ( !requestDone ) {
-                                       jQuery.ajax.handleComplete( s, xhr, status, data );
-                               }
-
-                               requestDone = true;
-                               if ( xhr ) {
-                                       xhr.onreadystatechange = jQuery.noop;
-                               }
-
-                       // The transfer is complete and the data is available, or the request timed out
-                       } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
-                               requestDone = true;
-                               xhr.onreadystatechange = jQuery.noop;
-
-                               status = isTimeout === "timeout" ?
-                                       "timeout" :
-                                       !jQuery.ajax.httpSuccess( xhr ) ?
-                                               "error" :
-                                               s.ifModified && jQuery.ajax.httpNotModified( xhr, s.url ) ?
-                                                       "notmodified" :
-                                                       "success";
-
-                               var errMsg;
-
-                               if ( status === "success" ) {
-                                       // Watch for, and catch, XML document parse errors
-                                       try {
-                                               // process the data (runs the xml through httpData regardless of callback)
-                                               data = jQuery.ajax.httpData( xhr, s.dataType, s );
-                                       } catch( parserError ) {
-                                               status = "parsererror";
-                                               errMsg = parserError;
-                                       }
-                               }
-
-                               // Make sure that the request was successful or notmodified
-                               if ( status === "success" || status === "notmodified" ) {
-                                       // JSONP handles its own success callback
-                                       if ( !jsonp ) {
-                                               jQuery.ajax.handleSuccess( s, xhr, status, data );
-                                       }
-                               } else {
-                                       jQuery.ajax.handleError( s, xhr, status, errMsg );
-                               }
-
-                               // Fire the complete handlers
-                               if ( !jsonp ) {
-                                       jQuery.ajax.handleComplete( s, xhr, status, data );
-                               }
-
-                               if ( isTimeout === "timeout" ) {
-                                       xhr.abort();
-                               }
-
-                               // Stop memory leaks
-                               if ( s.async ) {
-                                       xhr = null;
+               },
+               
+               // List of data converters
+               // 1) key format is "source_type => destination_type" (spaces required)
+               // 2) the catchall symbol "*" can be used for source_type
+               dataConverters: {
+               
+                       // Convert anything to text
+                       "* => text": function(data) {
+                               return "" + data;
+                       },
+                       
+                       // Text to html (no transformation)
+                       "text => html": function(data) {
+                               return data;
+                       },
+                       
+                       // Evaluate text as a json expression
+                       "text => json": jQuery.parseJSON,
+                       
+                       // Parse text as xml
+                       "text => xml": function(data) {
+                               var xml, parser;
+                               if ( window.DOMParser ) { // Standard
+                                       parser = new DOMParser();
+                                       xml = parser.parseFromString(data,"text/xml");
+                               } else { // IE
+                                       xml = new ActiveXObject("Microsoft.XMLDOM");
+                                       xml.async="false";
+                                       xml.loadXML(data);
                                }
+                               return xml;
                        }
-               };
-
-               // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
-               // Opera doesn't fire onreadystatechange at all on abort
-               try {
-                       var oldAbort = xhr.abort;
-                       xhr.abort = function() {
-                               // xhr.abort in IE7 is not a native JS function
-                               // and does not have a call property
-                               if ( xhr && oldAbort.call ) {
-                                       oldAbort.call( xhr );
-                               }
-
-                               onreadystatechange( "abort" );
-                       };
-               } catch( abortError ) {}
-
-               // Timeout checker
-               if ( s.async && s.timeout > 0 ) {
-                       setTimeout(function() {
-                               // Check to see if the request is still happening
-                               if ( xhr && !requestDone ) {
-                                       onreadystatechange( "timeout" );
-                               }
-                       }, s.timeout);
-               }
-
-               // Send the data
-               try {
-                       xhr.send( noContent || s.data == null ? null : s.data );
-
-               } catch( sendError ) {
-                       jQuery.ajax.handleError( s, xhr, null, sendError );
-
-                       // Fire the complete handlers
-                       jQuery.ajax.handleComplete( s, xhr, status, data );
                }
+       },
 
-               // firefox 1.5 doesn't fire statechange for sync requests
-               if ( !s.async ) {
-                       onreadystatechange();
+       // Main method
+       ajax: function( url , s ) {
+               
+               if ( arguments.length === 1 ) {
+                       s = url;
+                       url = s ? s.url : undefined;
                }
-
-               // return XMLHttpRequest to allow aborting the request etc.
-               return xhr;
+               
+               return jQuery.xhr().open( s ? s.type : undefined , url ).send( undefined , s );
+               
        },
 
        // Serialize an array of form elements or a set of
        // key/values into a query string
        param: function( a, traditional ) {
-               var s = [], add = function( key, value ) {
-                       // If value is a function, invoke it and return its value
-                       value = jQuery.isFunction(value) ? value() : value;
-                       s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
-               };
+               var s = [],
+                       add = function( key, value ) {
+                               // If value is a function, invoke it and return its value
+                               value = jQuery.isFunction(value) ? value() : value;
+                               s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+                       };
                
                // Set traditional to true for jQuery <= 1.3.2 behavior.
                if ( traditional === undefined ) {
@@ -558,7 +328,9 @@ function buildParams( prefix, obj, traditional, add ) {
                });
                        
        } else if ( !traditional && obj != null && typeof obj === "object" ) {
-               if ( jQuery.isEmptyObject( obj ) ) {
+               // If we see an array here, it is empty and should be treated as an empty
+               // object
+               if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) {
                        add( prefix, "" );
 
                // Serialize object item.
@@ -574,117 +346,16 @@ function buildParams( prefix, obj, traditional, add ) {
        }
 }
 
-jQuery.extend( jQuery.ajax, {
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
 
        // Counter for holding the number of active queries
        active: 0,
 
        // Last-Modified header cache for next request
        lastModified: {},
-       etag: {},
-
-       handleError: function( s, xhr, status, e ) {
-               // If a local callback was specified, fire it
-               if ( s.error ) {
-                       s.error.call( s.context, xhr, status, e );
-               }
-
-               // Fire the global callback
-               if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxError", [xhr, s, e] );
-               }
-       },
-
-       handleSuccess: function( s, xhr, status, data ) {
-               // If a local callback was specified, fire it and pass it the data
-               if ( s.success ) {
-                       s.success.call( s.context, data, status, xhr );
-               }
-
-               // Fire the global callback
-               if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
-               }
-       },
-
-       handleComplete: function( s, xhr, status ) {
-               // Process result
-               if ( s.complete ) {
-                       s.complete.call( s.context, xhr, status );
-               }
-
-               // The request was completed
-               if ( s.global ) {
-                       jQuery.ajax.triggerGlobal( s, "ajaxComplete", [xhr, s] );
-               }
-
-               // Handle the global AJAX counter
-               if ( s.global && jQuery.ajax.active-- === 1 ) {
-                       jQuery.event.trigger( "ajaxStop" );
-               }
-       },
-               
-       triggerGlobal: function( s, type, args ) {
-               (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
-       },
-
-       // Determines if an XMLHttpRequest was successful or not
-       httpSuccess: function( xhr ) {
-               try {
-                       // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
-                       return !xhr.status && location.protocol === "file:" ||
-                               xhr.status >= 200 && xhr.status < 300 ||
-                               xhr.status === 304 || xhr.status === 1223;
-               } catch(e) {}
-
-               return false;
-       },
-
-       // Determines if an XMLHttpRequest returns NotModified
-       httpNotModified: function( xhr, url ) {
-               var lastModified = xhr.getResponseHeader("Last-Modified"),
-                       etag = xhr.getResponseHeader("Etag");
-
-               if ( lastModified ) {
-                       jQuery.ajax.lastModified[url] = lastModified;
-               }
-
-               if ( etag ) {
-                       jQuery.ajax.etag[url] = etag;
-               }
-
-               return xhr.status === 304;
-       },
-
-       httpData: function( xhr, type, s ) {
-               var ct = xhr.getResponseHeader("content-type") || "",
-                       xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
-                       data = xml ? xhr.responseXML : xhr.responseText;
-
-               if ( xml && data.documentElement.nodeName === "parsererror" ) {
-                       jQuery.error( "parsererror" );
-               }
-
-               // Allow a pre-filtering function to sanitize the response
-               // s is checked to keep backwards compatibility
-               if ( s && s.dataFilter ) {
-                       data = s.dataFilter( data, type );
-               }
-
-               // The filter can actually parse the response
-               if ( typeof data === "string" ) {
-                       // Get the JavaScript object, if JSON is used.
-                       if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
-                               data = jQuery.parseJSON( data );
-
-                       // If the type is "script", eval it in global context
-                       } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
-                               jQuery.globalEval( data );
-                       }
-               }
-
-               return data;
-       }
+       etag: {}
 
 });
 
@@ -697,22 +368,24 @@ jQuery.extend( jQuery.ajax, {
  */
 if ( window.ActiveXObject ) {
        jQuery.ajaxSettings.xhr = function() {
-               if ( window.location.protocol !== "file:" ) {
-                       try {
-                               return new window.XMLHttpRequest();
-                       } catch(xhrError) {}
-               }
-
+       if ( window.location.protocol !== "file:" ) {
                try {
-                       return new window.ActiveXObject("Microsoft.XMLHTTP");
-               } catch(activeError) {}
+                       return new window.XMLHttpRequest();
+               } catch( xhrError ) {}
+       }
+       
+       try {
+               return new window.ActiveXObject("Microsoft.XMLHTTP");
+       } catch( activeError ) {}
        };
 }
 
+var testXHR = jQuery.ajaxSettings.xhr();
+
 // Does this browser support XHR requests?
-jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
+jQuery.support.ajax = !!testXHR;
 
-// For backwards compatibility
-jQuery.extend( jQuery.ajax );
+// Does this browser support crossDomain XHR requests
+jQuery.support.cors = testXHR && "withCredentials" in testXHR;
 
 })( jQuery );
index 147c353..78b1bfd 100644 (file)
@@ -1,6 +1,6 @@
 (function( jQuery ) {
 
-var rclass = /[\n\t]/g,
+var rclass = /[\n\t\r]/g,
        rspaces = /\s+/,
        rreturn = /\r/g,
        rspecialurl = /^(?:href|src|style)$/,
@@ -9,6 +9,19 @@ var rclass = /[\n\t]/g,
        rclickable = /^a(?:rea)?$/i,
        rradiocheck = /^(?:radio|checkbox)$/i;
 
+jQuery.props = {
+       "for": "htmlFor",
+       "class": "className",
+       readonly: "readOnly",
+       maxlength: "maxLength",
+       cellspacing: "cellSpacing",
+       rowspan: "rowSpan",
+       colspan: "colSpan",
+       tabindex: "tabIndex",
+       usemap: "useMap",
+       frameborder: "frameBorder"
+};
+
 jQuery.fn.extend({
        attr: function( name, value ) {
                return jQuery.access( this, name, value, true, jQuery.attr );
@@ -42,7 +55,9 @@ jQuery.fn.extend({
                                                elem.className = value;
 
                                        } else {
-                                               var className = " " + elem.className + " ", setClass = elem.className;
+                                               var className = " " + elem.className + " ",
+                                                       setClass = elem.className;
+
                                                for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
                                                        if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
                                                                setClass += " " + classNames[c];
@@ -90,7 +105,8 @@ jQuery.fn.extend({
        },
 
        toggleClass: function( value, stateVal ) {
-               var type = typeof value, isBool = typeof stateVal === "boolean";
+               var type = typeof value,
+                       isBool = typeof stateVal === "boolean";
 
                if ( jQuery.isFunction( value ) ) {
                        return this.each(function(i) {
@@ -102,7 +118,9 @@ jQuery.fn.extend({
                return this.each(function() {
                        if ( type === "string" ) {
                                // toggle individual class names
-                               var className, i = 0, self = jQuery(this),
+                               var className,
+                                       i = 0,
+                                       self = jQuery( this ),
                                        state = stateVal,
                                        classNames = value.split( rspaces );
 
@@ -187,7 +205,6 @@ jQuery.fn.extend({
                                if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
                                        return elem.getAttribute("value") === null ? "on" : elem.value;
                                }
-                               
 
                                // Everything else, we just grab the value
                                return (elem.value || "").replace(rreturn, "");
@@ -253,10 +270,10 @@ jQuery.extend({
                height: true,
                offset: true
        },
-               
+
        attr: function( elem, name, value, pass ) {
-               // don't set attributes on text and comment nodes
-               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+               // don't get/set attributes on text, comment and attribute nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
                        return undefined;
                }
 
@@ -282,7 +299,7 @@ jQuery.extend({
                                var parent = elem.parentNode;
                                if ( parent ) {
                                        parent.selectedIndex;
-       
+
                                        // Make sure that it also works with optgroups, see #5701
                                        if ( parent.parentNode ) {
                                                parent.parentNode.selectedIndex;
@@ -356,6 +373,11 @@ jQuery.extend({
                        // Non-existent attributes return null, we normalize to undefined
                        return attr === null ? undefined : attr;
                }
+               // Handle everything which isn't a DOM element node
+               if ( set ) {
+                       elem[ name ] = value;
+               }
+               return elem[ name ];
        }
 });
 
index 3389e83..346e52d 100644 (file)
@@ -215,7 +215,7 @@ jQuery.fn = jQuery.prototype = {
                        this.toArray() :
 
                        // Return just the object
-                       ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+                       ( num < 0 ? this[ this.length + num ] : this[ num ] );
        },
 
        // Take an array of elements and push it onto the stack
@@ -311,8 +311,11 @@ jQuery.fn = jQuery.prototype = {
 jQuery.fn.init.prototype = jQuery.fn;
 
 jQuery.extend = jQuery.fn.extend = function() {
-       // copy reference to target object
-       var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy, copyIsArray;
+        var options, name, src, copy, copyIsArray, clone,
+               target = arguments[0] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
 
        // Handle a deep copy situation
        if ( typeof target === "boolean" ) {
@@ -414,18 +417,21 @@ jQuery.extend({
                        // If there are functions bound, to execute
                        if ( readyList ) {
                                // Execute all of them
-                               var fn, i = 0;
-                               while ( (fn = readyList[ i++ ]) ) {
-                                       fn.call( document, jQuery );
-                               }
+                               var fn,
+                                       i = 0,
+                                       ready = readyList;
 
                                // Reset the list of functions
                                readyList = null;
-                       }
 
-                       // Trigger any bound ready events
-                       if ( jQuery.fn.triggerHandler ) {
-                               jQuery( document ).triggerHandler( "ready" );
+                               while ( (fn = ready[ i++ ]) ) {
+                                       fn.call( document, jQuery );
+                               }
+
+                               // Trigger any bound ready events
+                               if ( jQuery.fn.trigger ) {
+                                       jQuery( document ).trigger( "ready" ).unbind( "ready" );
+                               }
                        }
                }
        },
@@ -678,7 +684,8 @@ jQuery.extend({
        },
 
        merge: function( first, second ) {
-               var i = first.length, j = 0;
+               var i = first.length,
+                       j = 0;
 
                if ( typeof second.length === "number" ) {
                        for ( var l = second.length; j < l; j++ ) {
@@ -726,6 +733,7 @@ jQuery.extend({
                        }
                }
 
+               // Flatten any nested arrays
                return ret.concat.apply( [], ret );
        },
 
index d0e55db..8a83c60 100644 (file)
@@ -12,8 +12,8 @@ var ralpha = /alpha\([^)]*\)/i,
        cssHeight = [ "Top", "Bottom" ],
        curCSS,
 
-       // cache check for defaultView.getComputedStyle
-       getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,
+       getComputedStyle,
+       currentStyle,
 
        fcamelCase = function( all, letter ) {
                return letter.toUpperCase();
@@ -169,7 +169,29 @@ jQuery.each(["height", "width"], function( i, name ) {
                                        });
                                }
 
-                               return val + "px";
+                               if ( val <= 0 ) {
+                                       val = curCSS( elem, name, name );
+
+                                       if ( val === "0px" && currentStyle ) {
+                                               val = currentStyle( elem, name, name );
+                                       }
+
+                                       if ( val != null ) {
+                                               // Should return "auto" instead of 0, use 0 for
+                                               // temporary backwards-compat
+                                               return val === "" || val === "auto" ? "0px" : val;
+                                       }
+                               }
+
+                               if ( val < 0 || val == null ) {
+                                       val = elem.style[ name ];
+
+                                       // Should return "auto" instead of 0, use 0 for
+                                       // temporary backwards-compat
+                                       return val === "" || val === "auto" ? "0px" : val;
+                               }
+
+                               return typeof val === "string" ? val : val + "px";
                        }
                },
 
@@ -218,8 +240,8 @@ if ( !jQuery.support.opacity ) {
        };
 }
 
-if ( getComputedStyle ) {
-       curCSS = function( elem, newName, name ) {
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+       getComputedStyle = function( elem, newName, name ) {
                var ret, defaultView, computedStyle;
 
                name = name.replace( rupper, "-$1" ).toLowerCase();
@@ -230,14 +252,20 @@ if ( getComputedStyle ) {
 
                if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
                        ret = computedStyle.getPropertyValue( name );
+                       if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+                               ret = jQuery.style( elem, name );
+                       }
                }
 
                return ret;
        };
+}
 
-} else if ( document.documentElement.currentStyle ) {
-       curCSS = function( elem, name ) {
-               var left, rsLeft, ret = elem.currentStyle && elem.currentStyle[ name ], style = elem.style;
+if ( document.documentElement.currentStyle ) {
+       currentStyle = function( elem, name ) {
+               var left, rsLeft,
+                       ret = elem.currentStyle && elem.currentStyle[ name ],
+                       style = elem.style;
 
                // From the awesome hack by Dean Edwards
                // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
@@ -259,10 +287,12 @@ if ( getComputedStyle ) {
                        elem.runtimeStyle.left = rsLeft;
                }
 
-               return ret;
+               return ret === "" ? "auto" : ret;
        };
 }
 
+curCSS = getComputedStyle || currentStyle;
+
 function getWH( elem, name, extra ) {
        var which = name === "width" ? cssWidth : cssHeight,
                val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
@@ -289,7 +319,8 @@ function getWH( elem, name, extra ) {
 
 if ( jQuery.expr && jQuery.expr.filters ) {
        jQuery.expr.filters.hidden = function( elem ) {
-               var width = elem.offsetWidth, height = elem.offsetHeight;
+               var width = elem.offsetWidth,
+                       height = elem.offsetHeight;
 
                return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
        };
index bb7febf..4d1d1bd 100644 (file)
@@ -22,6 +22,14 @@ jQuery.extend({
                "applet": true
        },
 
+       hasData: function( elem ) {
+               if ( elem.nodeType ) {
+                       elem = jQuery.cache[ elem[jQuery.expando] ];
+               }
+
+               return !!elem && !jQuery.isEmptyObject(elem);
+       },
+
        data: function( elem, name, data ) {
                if ( !jQuery.acceptData( elem ) ) {
                        return;
@@ -135,8 +143,26 @@ jQuery.extend({
 
 jQuery.fn.extend({
        data: function( key, value ) {
+               var data = null;
+
                if ( typeof key === "undefined" ) {
-                       return this.length ? jQuery.data( this[0] ) : null;
+                       if ( this.length ) {
+                               data = jQuery.data( this[0] );
+
+                               if ( this[0].nodeType === 1 ) {
+                                       var attr = this[0].attributes, name;
+                                       for ( var i = 0, l = attr.length; i < l; i++ ) {
+                                               name = attr[i].name;
+
+                                               if ( name.indexOf( "data-" ) === 0 ) {
+                                                       name = name.substr( 5 );
+                                                       dataAttr( this[0], name, data[ name ] );
+                                               }
+                                       }
+                               }
+                       }
+
+                       return data;
 
                } else if ( typeof key === "object" ) {
                        return this.each(function() {
@@ -148,31 +174,12 @@ jQuery.fn.extend({
                parts[1] = parts[1] ? "." + parts[1] : "";
 
                if ( value === undefined ) {
-                       var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+                       data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
 
                        // Try to fetch any internally stored data first
                        if ( data === undefined && this.length ) {
                                data = jQuery.data( this[0], key );
-
-                               // If nothing was found internally, try to fetch any
-                               // data from the HTML5 data-* attribute
-                               if ( data === undefined && this[0].nodeType === 1 ) {
-                                       data = this[0].getAttribute( "data-" + key );
-
-                                       if ( typeof data === "string" ) {
-                                               try {
-                                                       data = data === "true" ? true :
-                                                               data === "false" ? false :
-                                                               data === "null" ? null :
-                                                               !jQuery.isNaN( data ) ? parseFloat( data ) :
-                                                               rbrace.test( data ) ? jQuery.parseJSON( data ) :
-                                                               data;
-                                               } catch( e ) {}
-
-                                       } else {
-                                               data = undefined;
-                                       }
-                               }
+                               data = dataAttr( this[0], key, data );
                        }
 
                        return data === undefined && parts[1] ?
@@ -181,7 +188,8 @@ jQuery.fn.extend({
 
                } else {
                        return this.each(function() {
-                               var $this = jQuery( this ), args = [ parts[0], value ];
+                               var $this = jQuery( this ),
+                                       args = [ parts[0], value ];
 
                                $this.triggerHandler( "setData" + parts[1] + "!", args );
                                jQuery.data( this, key, value );
@@ -197,4 +205,31 @@ jQuery.fn.extend({
        }
 });
 
+function dataAttr( elem, key, data ) {
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+               data = elem.getAttribute( "data-" + key );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = data === "true" ? true :
+                               data === "false" ? false :
+                               data === "null" ? null :
+                               !jQuery.isNaN( data ) ? parseFloat( data ) :
+                                       rbrace.test( data ) ? jQuery.parseJSON( data ) :
+                                       data;
+                       } catch( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       jQuery.data( elem, key, data );
+
+               } else {
+                       data = undefined;
+               }
+       }
+
+       return data;
+}
+
 })( jQuery );
index 5aafbf4..f35b0ac 100644 (file)
@@ -33,27 +33,31 @@ jQuery.each([ "Height", "Width" ], function( i, name ) {
                        });
                }
 
-               return jQuery.isWindow( elem ) ?
+               if ( jQuery.isWindow( elem ) ) {
                        // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
-                       elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
-                       elem.document.body[ "client" + name ] :
-
-                       // Get document width or height
-                       (elem.nodeType === 9) ? // is it a document
-                               // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
-                               Math.max(
-                                       elem.documentElement["client" + name],
-                                       elem.body["scroll" + name], elem.documentElement["scroll" + name],
-                                       elem.body["offset" + name], elem.documentElement["offset" + name]
-                               ) :
-
-                               // Get or set width or height on the element
-                               size === undefined ?
-                                       // Get width or height on the element
-                                       parseFloat( jQuery.css( elem, type ) ) :
-
-                                       // Set the width or height on the element (default to pixels if value is unitless)
-                                       this.css( type, typeof size === "string" ? size : size + "px" );
+                       return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+                               elem.document.body[ "client" + name ];
+
+               // Get document width or height
+               } else if ( elem.nodeType === 9 ) {
+                       // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+                       return Math.max(
+                               elem.documentElement["client" + name],
+                               elem.body["scroll" + name], elem.documentElement["scroll" + name],
+                               elem.body["offset" + name], elem.documentElement["offset" + name]
+                       );
+
+               // Get or set width or height on the element
+               } else if ( size === undefined ) {
+                       var orig = jQuery.css( elem, type ),
+                               ret = parseFloat( orig );
+
+                       return jQuery.isNaN( ret ) ? orig : ret;
+
+               // Set the width or height on the element (default to pixels if value is unitless)
+               } else {
+                       return this.css( type, typeof size === "string" ? size : size + "px" );
+               }
        };
 
 });
index 241dbd0..6007074 100644 (file)
@@ -2,7 +2,7 @@
 
 var elemdisplay = {},
        rfxtypes = /^(?:toggle|show|hide)$/,
-       rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+       rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
        timerId,
        fxAttrs = [
                // height animations
@@ -15,28 +15,39 @@ var elemdisplay = {},
 
 jQuery.fn.extend({
        show: function( speed, easing, callback ) {
+               var elem, display;
+
                if ( speed || speed === 0 ) {
                        return this.animate( genFx("show", 3), speed, easing, callback);
+
                } else {
                        for ( var i = 0, j = this.length; i < j; i++ ) {
+                               elem = this[i];
+                               display = elem.style.display;
+
                                // Reset the inline display of this element to learn if it is
                                // being hidden by cascaded rules or not
-                               if ( !jQuery.data(this[i], "olddisplay") && this[i].style.display === "none" ) {
-                                       this[i].style.display = "";
+                               if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
+                                       display = elem.style.display = "";
                                }
 
                                // Set elements which have been overridden with display: none
                                // in a stylesheet to whatever the default browser style is
                                // for such an element
-                               if ( this[i].style.display === "" && jQuery.css( this[i], "display" ) === "none" ) {
-                                       jQuery.data(this[i], "olddisplay", defaultDisplay(this[i].nodeName));
+                               if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+                                       jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
                                }
                        }
 
                        // Set the display of most of the elements in a second loop
                        // to avoid the constant reflow
                        for ( i = 0; i < j; i++ ) {
-                               this[i].style.display = jQuery.data(this[i], "olddisplay") || "";
+                               elem = this[i];
+                               display = elem.style.display;
+
+                               if ( display === "" || display === "none" ) {
+                                       elem.style.display = jQuery.data(elem, "olddisplay") || "";
+                               }
                        }
 
                        return this;
@@ -49,9 +60,10 @@ jQuery.fn.extend({
 
                } else {
                        for ( var i = 0, j = this.length; i < j; i++ ) {
-                               var old = jQuery.data(this[i], "olddisplay");
-                               if ( !old ) {
-                                       jQuery.data( this[i], "olddisplay", jQuery.css( this[i], "display" ) );
+                               var display = jQuery.css( this[i], "display" );
+        
+                               if ( display !== "none" && !jQuery.data( this[i], "olddisplay" ) ) {
+                                       jQuery.data( this[i], "olddisplay", display );
                                }
                        }
 
@@ -100,7 +112,7 @@ jQuery.fn.extend({
                }
 
                return this[ optall.queue === false ? "each" : "queue" ](function() {
-                       // XXX â€˜this’ does not always have a nodeName when running the
+                       // XXX 'this' does not always have a nodeName when running the
                        // test suite
 
                        var opt = jQuery.extend({}, optall), p,
@@ -173,7 +185,7 @@ jQuery.fn.extend({
 
                                } else {
                                        var parts = rfxnum.exec(val),
-                                               start = e.cur(true) || 0;
+                                               start = e.cur() || 0;
 
                                        if ( parts ) {
                                                var end = parseFloat( parts[2] ),
@@ -181,9 +193,9 @@ jQuery.fn.extend({
 
                                                // We need to compute starting value
                                                if ( unit !== "px" ) {
-                                                       self.style[ name ] = (end || 1) + unit;
-                                                       start = ((end || 1) / e.cur(true)) * start;
-                                                       self.style[ name ] = start + unit;
+                                                       jQuery.style( self, name, (end || 1) + unit);
+                                                       start = ((end || 1) / e.cur()) * start;
+                                                       jQuery.style( self, name, start + unit);
                                                }
 
                                                // If a +=/-= token was provided, we're doing a relative animation
@@ -251,7 +263,8 @@ jQuery.each({
        slideUp: genFx("hide", 1),
        slideToggle: genFx("toggle", 1),
        fadeIn: { opacity: "show" },
-       fadeOut: { opacity: "hide" }
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
 }, function( name, props ) {
        jQuery.fn[ name ] = function( speed, easing, callback ) {
                return this.animate( props, speed, easing, callback );
@@ -329,6 +342,9 @@ jQuery.fx.prototype = {
 
        // Start an animation from one number to another
        custom: function( from, to, unit ) {
+               var self = this,
+                       fx = jQuery.fx;
+
                this.startTime = jQuery.now();
                this.start = from;
                this.end = to;
@@ -336,7 +352,6 @@ jQuery.fx.prototype = {
                this.now = this.start;
                this.pos = this.state = 0;
 
-               var self = this, fx = jQuery.fx;
                function t( gotoEnd ) {
                        return self.step(gotoEnd);
                }
@@ -393,7 +408,9 @@ jQuery.fx.prototype = {
                        if ( done ) {
                                // Reset the overflow
                                if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
-                                       var elem = this.elem, options = this.options;
+                                       var elem = this.elem,
+                                               options = this.options;
+
                                        jQuery.each( [ "", "X", "Y" ], function (index, value) {
                                                elem.style[ "overflow" + value ] = options.overflow[index];
                                        } );
index 7a10a12..fd470e7 100644 (file)
@@ -7,7 +7,8 @@ var rnamespaces = /\.(.*)$/,
        rescape = /[^\w\s.|`]/g,
        fcleanup = function( nm ) {
                return nm.replace(rescape, "\\$&");
-       };
+       },
+       focusCounts = { focusin: 0, focusout: 0 };
 
 /*
  * A number of helper functions used for managing events.
@@ -31,6 +32,9 @@ jQuery.event = {
 
                if ( handler === false ) {
                        handler = returnFalse;
+               } else if ( !handler ) {
+                       // Fixes bug #7229. Fix recommended by jdalton
+                 return;
                }
 
                var handleObjIn, handleObj;
@@ -54,7 +58,10 @@ jQuery.event = {
                        return;
                }
 
-               var events = elemData.events,
+               // Use a key less likely to result in collisions for plain JS objects.
+               // Fixes bug #7150.
+               var eventKey = elem.nodeType ? "events" : "__events__",
+                       events = elemData[ eventKey ],
                        eventHandle = elemData.handle;
                        
                if ( typeof events === "function" ) {
@@ -68,7 +75,7 @@ jQuery.event = {
                        if ( !elem.nodeType ) {
                                // On plain objects, create a fn that acts as the holder
                                // of the values to avoid JSON serialization of event data
-                               elemData.events = elemData = function(){};
+                               elemData[ eventKey ] = elemData = function(){};
                        }
 
                        elemData.events = events = {};
@@ -170,8 +177,9 @@ jQuery.event = {
                }
 
                var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+                       eventKey = elem.nodeType ? "events" : "__events__",
                        elemData = jQuery.data( elem ),
-                       events = elemData && elemData.events;
+                       events = elemData && elemData[ eventKey ];
 
                if ( !elemData || !events ) {
                        return;
@@ -282,7 +290,7 @@ jQuery.event = {
                        delete elemData.handle;
 
                        if ( typeof elemData === "function" ) {
-                               delete elem.events;
+                               jQuery.removeData( elem, eventKey );
 
                        } else if ( jQuery.isEmptyObject( elemData ) ) {
                                jQuery.removeData( elem );
@@ -346,7 +354,7 @@ jQuery.event = {
                // Trigger the event, it is assumed that "handle" is a function
                var handle = elem.nodeType ?
                        jQuery.data( elem, "handle" ) :
-                       elem.events && elem.events.handle;
+                       (jQuery.data( elem, "__events__" ) || {}).handle;
 
                if ( handle ) {
                        handle.apply( elem, data );
@@ -370,8 +378,10 @@ jQuery.event = {
                        jQuery.event.trigger( event, data, parent, true );
 
                } else if ( !event.isDefaultPrevented() ) {
-                       var target = event.target, old, targetType = type.replace(rnamespaces, ""),
-                               isClick = jQuery.nodeName(target, "a") && targetType === "click",
+                       var old,
+                               target = event.target,
+                               targetType = type.replace( rnamespaces, "" ),
+                               isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
                                special = jQuery.event.special[ targetType ] || {};
 
                        if ( (!special._default || special._default.call( elem, event ) === false) && 
@@ -403,7 +413,9 @@ jQuery.event = {
        },
 
        handle: function( event ) {
-               var all, handlers, namespaces, namespace_sort = [], namespace_re, events, args = jQuery.makeArray( arguments );
+               var all, handlers, namespaces, namespace_re, events,
+                       namespace_sort = [],
+                       args = jQuery.makeArray( arguments );
 
                event = args[0] = jQuery.event.fix( event || window.event );
                event.currentTarget = this;
@@ -420,7 +432,7 @@ jQuery.event = {
 
                event.namespace = event.namespace || namespace_sort.join(".");
 
-               events = jQuery.data(this, "events");
+               events = jQuery.data(this, this.nodeType ? "events" : "__events__");
 
                if ( typeof events === "function" ) {
                        events = events.events;
@@ -482,7 +494,8 @@ jQuery.event = {
 
                // Fix target property, if necessary
                if ( !event.target ) {
-                       event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
+                       // Fixes #1925 where srcElement might not be defined either
+                       event.target = event.srcElement || document;
                }
 
                // check if target is a textnode (safari)
@@ -497,7 +510,9 @@ jQuery.event = {
 
                // Calculate pageX/Y if missing and clientX/Y available
                if ( event.pageX == null && event.clientX != null ) {
-                       var doc = document.documentElement, body = document.body;
+                       var doc = document.documentElement,
+                               body = document.body;
+
                        event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
                        event.pageY = event.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
                }
@@ -701,9 +716,10 @@ if ( !jQuery.support.submitBubbles ) {
 
        jQuery.event.special.submit = {
                setup: function( data, namespaces ) {
-                       if ( this.nodeName.toLowerCase() !== "form" ) {
+                       if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) {
                                jQuery.event.add(this, "click.specialSubmit", function( e ) {
-                                       var elem = e.target, type = elem.type;
+                                       var elem = e.target,
+                                               type = elem.type;
 
                                        if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
                                                e.liveFired = undefined;
@@ -712,7 +728,8 @@ if ( !jQuery.support.submitBubbles ) {
                                });
         
                                jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
-                                       var elem = e.target, type = elem.type;
+                                       var elem = e.target,
+                                               type = elem.type;
 
                                        if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
                                                e.liveFired = undefined;
@@ -787,6 +804,8 @@ if ( !jQuery.support.changeBubbles ) {
                filters: {
                        focusout: testChange, 
 
+                       beforedeactivate: testChange,
+
                        click: function( e ) {
                                var elem = e.target, type = elem.type;
 
@@ -851,17 +870,21 @@ if ( document.addEventListener ) {
        jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
                jQuery.event.special[ fix ] = {
                        setup: function() {
-                               this.addEventListener( orig, handler, true );
+                               if ( focusCounts[fix]++ === 0 ) {
+                                       document.addEventListener( orig, handler, true );
+                               }
                        }, 
                        teardown: function() { 
-                               this.removeEventListener( orig, handler, true );
+                               if ( --focusCounts[fix] === 0 ) {
+                                       document.removeEventListener( orig, handler, true );
+                               }
                        }
                };
 
                function handler( e ) { 
                        e = jQuery.event.fix( e );
                        e.type = fix;
-                       return jQuery.event.handle.call( this, e );
+                       return jQuery.event.trigger( e, null, e.target );
                }
        });
 }
@@ -947,7 +970,8 @@ jQuery.fn.extend({
 
        toggle: function( fn ) {
                // Save reference to arguments for access in closure
-               var args = arguments, i = 1;
+               var args = arguments,
+                       i = 1;
 
                // link all the functions, so any of them can unbind this click handler
                while ( i < args.length ) {
@@ -1042,19 +1066,20 @@ jQuery.each(["live", "die"], function( i, name ) {
 });
 
 function liveHandler( event ) {
-       var stop, maxLevel, elems = [], selectors = [],
-               related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
-               events = jQuery.data( this, "events" );
+       var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+               elems = [],
+               selectors = [],
+               events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
 
        if ( typeof events === "function" ) {
                events = events.events;
        }
 
-       // Make sure we avoid non-left-click bubbling in Firefox (#3861)
-       if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+       // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911)
+       if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) {
                return;
        }
-
+       
        if ( event.namespace ) {
                namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
        }
@@ -1118,6 +1143,9 @@ function liveHandler( event ) {
                        if ( ret === false ) {
                                stop = false;
                        }
+                       if ( event.isImmediatePropagationStopped() ) {
+                               break;
+                       }
                }
        }
 
index 325f303..5f4b15d 100644 (file)
@@ -7,8 +7,8 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
        rtbody = /<tbody/i,
        rhtml = /<|&#?\w+;/,
        rnocache = /<(?:script|object|embed|option|style)/i,
-       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,  // checked="checked" or checked (html5)
-       raction = /\=([^="'>\s]+\/)>/g,
+       // checked="checked" or checked (html5)
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
        wrapMap = {
                option: [ 1, "<select multiple='multiple'>", "</select>" ],
                legend: [ 1, "<fieldset>", "</fieldset>" ],
@@ -33,7 +33,8 @@ jQuery.fn.extend({
        text: function( text ) {
                if ( jQuery.isFunction(text) ) {
                        return this.each(function(i) {
-                               var self = jQuery(this);
+                               var self = jQuery( this );
+
                                self.text( text.call(this, i, self.text()) );
                        });
                }
@@ -82,7 +83,8 @@ jQuery.fn.extend({
                }
 
                return this.each(function() {
-                       var self = jQuery( this ), contents = self.contents();
+                       var self = jQuery( this ),
+                               contents = self.contents();
 
                        if ( contents.length ) {
                                contents.wrapAll( html );
@@ -146,7 +148,7 @@ jQuery.fn.extend({
                        return set;
                }
        },
-       
+
        // keepData is for internal use only--do not document
        remove: function( selector, keepData ) {
                for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
@@ -161,7 +163,7 @@ jQuery.fn.extend({
                                }
                        }
                }
-               
+
                return this;
        },
 
@@ -177,36 +179,37 @@ jQuery.fn.extend({
                                elem.removeChild( elem.firstChild );
                        }
                }
-               
+
                return this;
        },
 
        clone: function( events ) {
                // Do the clone
                var ret = this.map(function() {
-                       if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
-                               // IE copies events bound via attachEvent when
-                               // using cloneNode. Calling detachEvent on the
-                               // clone will also remove the events from the orignal
-                               // In order to get around this, we use innerHTML.
-                               // Unfortunately, this means some modifications to
-                               // attributes in IE that are actually only stored
-                               // as properties will not be copied (such as the
-                               // the name attribute on an input).
-                               var html = this.outerHTML, ownerDocument = this.ownerDocument;
-                               if ( !html ) {
-                                       var div = ownerDocument.createElement("div");
-                                       div.appendChild( this.cloneNode(true) );
-                                       html = div.innerHTML;
+                       var clone = this.cloneNode(true);
+                       if ( !jQuery.support.noCloneEvent && (this.nodeType === 1 || this.nodeType === 11) && !jQuery.isXMLDoc(this) ) {
+                               // IE copies events bound via attachEvent when using cloneNode.
+                               // Calling detachEvent on the clone will also remove the events
+                               // from the original. In order to get around this, we use some
+                               // proprietary methods to clear the events. Thanks to MooTools
+                               // guys for this hotness.
+
+                               // Using Sizzle here is crazy slow, so we use getElementsByTagName
+                               // instead
+                               var srcElements = this.getElementsByTagName("*"),
+                                       destElements = clone.getElementsByTagName("*");
+
+                               // Weird iteration because IE will replace the length property
+                               // with an element if you are cloning the body and one of the
+                               // elements on the page has a name or id of "length"
+                               for ( var i = 0; srcElements[i]; ++i ) {
+                                       cloneFixAttributes( srcElements[i], destElements[i] );
                                }
 
-                               return jQuery.clean([html.replace(rinlinejQuery, "")
-                                       // Handle the case in IE 8 where action=/test/> self-closes a tag
-                                       .replace(raction, '="$1">')
-                                       .replace(rleadingWhitespace, "")], ownerDocument)[0];
-                       } else {
-                               return this.cloneNode(true);
+                               cloneFixAttributes( this, clone );
                        }
+
+                       return clone;
                });
 
                // Copy the events from the original to the clone
@@ -248,7 +251,8 @@ jQuery.fn.extend({
 
                } else if ( jQuery.isFunction( value ) ) {
                        this.each(function(i){
-                               var self = jQuery(this);
+                               var self = jQuery( this );
+
                                self.html( value.call(this, i, self.html()) );
                        });
 
@@ -271,13 +275,14 @@ jQuery.fn.extend({
                        }
 
                        if ( typeof value !== "string" ) {
-                               value = jQuery(value).detach();
+                               value = jQuery( value ).detach();
                        }
 
                        return this.each(function() {
-                               var next = this.nextSibling, parent = this.parentNode;
+                               var next = this.nextSibling,
+                                       parent = this.parentNode;
 
-                               jQuery(this).remove();
+                               jQuery( this ).remove();
 
                                if ( next ) {
                                        jQuery(next).before( value );
@@ -295,7 +300,9 @@ jQuery.fn.extend({
        },
 
        domManip: function( args, table, callback ) {
-               var results, first, value = args[0], scripts = [], fragment, parent;
+               var results, first, fragment, parent,
+                       value = args[0],
+                       scripts = [];
 
                // We can't cloneNode fragments that contain checked, in WebKit
                if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
@@ -322,9 +329,9 @@ jQuery.fn.extend({
                        } else {
                                results = jQuery.buildFragment( args, this, scripts );
                        }
-                       
+
                        fragment = results.fragment;
-                       
+
                        if ( fragment.childNodes.length === 1 ) {
                                first = fragment = fragment.firstChild;
                        } else {
@@ -340,7 +347,7 @@ jQuery.fn.extend({
                                                        root(this[i], first) :
                                                        this[i],
                                                i > 0 || results.cacheable || this.length > 1  ?
-                                                       fragment.cloneNode(true) :
+                                                       jQuery(fragment).clone(true)[0] :
                                                        fragment
                                        );
                                }
@@ -363,28 +370,72 @@ function root( elem, cur ) {
 }
 
 function cloneCopyEvent(orig, ret) {
-       var i = 0;
-
-       ret.each(function() {
-               if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+       ret.each(function (nodeIndex) {
+               if ( this.nodeType !== 1 || !jQuery.hasData(orig[nodeIndex]) ) {
                        return;
                }
 
-               var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;
+               // XXX remove for 1.5 RC or merge back in if there is actually a reason for this check that has been
+               // unexposed by unit tests
+               if ( this.nodeName !== (orig[nodeIndex] && orig[nodeIndex].nodeName) ) {
+                       throw "Cloned data mismatch";
+               }
+
+               var oldData = jQuery.data( orig[nodeIndex] ),
+                       curData = jQuery.data( this, oldData ),
+                       events = oldData && oldData.events;
 
                if ( events ) {
                        delete curData.handle;
                        curData.events = {};
 
                        for ( var type in events ) {
-                               for ( var handler in events[ type ] ) {
-                                       jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+                               for ( var i = 0, l = events[ type ].length; i < l; i++ ) {
+                                       jQuery.event.add( this, type, events[ type ][ i ], events[ type ][ i ].data );
                                }
                        }
                }
        });
 }
 
+function cloneFixAttributes(src, dest) {
+       // We do not need to do anything for non-Elements
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       var nodeName = dest.nodeName.toLowerCase();
+
+       // clearAttributes removes the attributes, which we don't want,
+       // but also removes the attachEvent events, which we *do* want
+       dest.clearAttributes();
+
+       // mergeAttributes, in contrast, only merges back on the
+       // original attributes, not the events
+       dest.mergeAttributes(src);
+
+       // IE6-8 fail to clone children inside object elements that use
+       // the proprietary classid attribute value (rather than the type
+       // attribute) to identify the type of content to display
+       if ( nodeName === "object" ) {
+               dest.outerHTML = src.outerHTML;
+
+       // IE6-8 fails to persist the checked state of a cloned checkbox
+       // or radio button
+       } else if ( nodeName === "input" && src.checked ) {
+               dest.defaultChecked = dest.checked = src.checked;
+
+       // IE6-8 fails to return the selected option to the default selected
+       // state when cloning options
+       } else if ( nodeName === "option" ) {
+               dest.selected = src.defaultSelected;
+       }
+
+       // Event data gets referenced instead of copied if the expando
+       // gets copied too
+       dest.removeAttribute( jQuery.expando );
+}
+
 jQuery.buildFragment = function( args, nodes, scripts ) {
        var fragment, cacheable, cacheresults,
                doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
@@ -427,20 +478,21 @@ jQuery.each({
        replaceAll: "replaceWith"
 }, function( name, original ) {
        jQuery.fn[ name ] = function( selector ) {
-               var ret = [], insert = jQuery( selector ),
+               var ret = [],
+                       insert = jQuery( selector ),
                        parent = this.length === 1 && this[0].parentNode;
-               
+
                if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
                        insert[ original ]( this[0] );
                        return this;
-                       
+
                } else {
                        for ( var i = 0, l = insert.length; i < l; i++ ) {
                                var elems = (i > 0 ? this.clone(true) : this).get();
                                jQuery( insert[i] )[ original ]( elems );
                                ret = ret.concat( elems );
                        }
-               
+
                        return this.pushStack( ret, name, insert.selector );
                }
        };
@@ -528,7 +580,7 @@ jQuery.extend({
                        for ( i = 0; ret[i]; i++ ) {
                                if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
                                        scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
-                               
+
                                } else {
                                        if ( ret[i].nodeType === 1 ) {
                                                ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
@@ -540,22 +592,22 @@ jQuery.extend({
 
                return ret;
        },
-       
+
        cleanData: function( elems ) {
                var data, id, cache = jQuery.cache,
                        special = jQuery.event.special,
                        deleteExpando = jQuery.support.deleteExpando;
-               
+
                for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
                        if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
                                continue;
                        }
 
                        id = elem[ jQuery.expando ];
-                       
+
                        if ( id ) {
                                data = cache[ id ];
-                               
+
                                if ( data && data.events ) {
                                        for ( var type in data.events ) {
                                                if ( special[ type ] ) {
@@ -566,14 +618,14 @@ jQuery.extend({
                                                }
                                        }
                                }
-                               
+
                                if ( deleteExpando ) {
                                        delete elem[ jQuery.expando ];
 
                                } else if ( elem.removeAttribute ) {
                                        elem.removeAttribute( jQuery.expando );
                                }
-                               
+
                                delete cache[ id ];
                        }
                }
index bbb19c2..3fb2917 100644 (file)
@@ -23,14 +23,17 @@ if ( "getBoundingClientRect" in document.documentElement ) {
 
                try {
                        box = elem.getBoundingClientRect();
+               } catch(e) {}
 
-               } catch(e) {
-                       return { top: 0, left: 0 };
+               var doc = elem.ownerDocument,
+                       docElem = doc.documentElement;
+
+               // Make sure we're not dealing with a disconnected DOM node
+               if ( !box || !jQuery.contains( docElem, elem ) ) {
+                       return box || { top: 0, left: 0 };
                }
 
-               var doc = elem.ownerDocument,
-                       body = doc.body,
-                       docElem = doc.documentElement,
+               var body = doc.body,
                        win = getWindow(doc),
                        clientTop  = docElem.clientTop  || body.clientTop  || 0,
                        clientLeft = docElem.clientLeft || body.clientLeft || 0,
@@ -62,11 +65,16 @@ if ( "getBoundingClientRect" in document.documentElement ) {
 
                jQuery.offset.initialize();
 
-               var offsetParent = elem.offsetParent, prevOffsetParent = elem,
-                       doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,
-                       body = doc.body, defaultView = doc.defaultView,
+               var computedStyle,
+                       offsetParent = elem.offsetParent,
+                       prevOffsetParent = elem,
+                       doc = elem.ownerDocument,
+                       docElem = doc.documentElement,
+                       body = doc.body,
+                       defaultView = doc.defaultView,
                        prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
-                       top = elem.offsetTop, left = elem.offsetLeft;
+                       top = elem.offsetTop,
+                       left = elem.offsetLeft;
 
                while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
                        if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
@@ -148,7 +156,8 @@ jQuery.offset = {
        },
 
        bodyOffset: function( body ) {
-               var top = body.offsetTop, left = body.offsetLeft;
+               var top = body.offsetTop,
+                       left = body.offsetLeft;
 
                jQuery.offset.initialize();
 
index 23d4360..735b0e1 100644 (file)
@@ -27,7 +27,8 @@ jQuery.extend({
        dequeue: function( elem, type ) {
                type = type || "fx";
 
-               var queue = jQuery.queue( elem, type ), fn = queue.shift();
+               var queue = jQuery.queue( elem, type ),
+                       fn = queue.shift();
 
                // If the fx queue is dequeued, always remove the progress sentinel
                if ( fn === "inprogress" ) {
index c2ffa45..e4c3ea9 100644 (file)
@@ -61,6 +61,7 @@
                optSelected: opt.selected,
 
                // Will be defined later
+               deleteExpando: true,
                optDisabled: false,
                checkClone: false,
                scriptEval: false,
                delete window[ id ];
        }
 
+       // Test to see if it's possible to delete an expando from an element
+       // Fails in Internet Explorer
+       try {
+               delete script.test;
+
+       } catch(e) {
+               jQuery.support.deleteExpando = false;
+       }
+
        root.removeChild( script );
 
        if ( div.attachEvent && div.fireEvent ) {
                        jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
                }
 
-               div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+               div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
                var tds = div.getElementsByTagName("td");
 
                // Check if table cells still have offsetWidth/Height when they are set
        // release memory in IE
        root = script = div = all = a = null;
 })();
-
-jQuery.props = {
-       "for": "htmlFor",
-       "class": "className",
-       readonly: "readOnly",
-       maxlength: "maxLength",
-       cellspacing: "cellSpacing",
-       rowspan: "rowSpan",
-       colspan: "colSpan",
-       tabindex: "tabIndex",
-       usemap: "useMap",
-       frameborder: "frameBorder"
-};
-
 })( jQuery );
diff --git a/src/transports/jsonp.js b/src/transports/jsonp.js
new file mode 100644 (file)
index 0000000..d9e77f2
--- /dev/null
@@ -0,0 +1,89 @@
+(function( jQuery ) {
+
+var jsc = jQuery.now(),
+       jsre = /\=\?(&|$)/,
+       rquery_jsonp = /\?/;
+
+// Default jsonp callback name
+jQuery.ajaxSettings.jsonpCallback = function() {
+       return "jsonp" + jsc++;
+};
+
+// Normalize jsonp queries
+// 1) put callback parameter in url or data
+// 2) ensure transportDataType is json
+// 3) ensure options jsonp is always provided so that jsonp requests are always
+//    json request with the jsonp option set
+jQuery.xhr.prefilter( function(s) {
+       
+       var transportDataType = s.dataTypes[0];
+       
+       if ( s.jsonp ||
+               transportDataType === "jsonp" ||
+               transportDataType === "json" && ( jsre.test(s.url) || typeof(s.data) === "string" && jsre.test(s.data) ) ) {
+
+               var jsonp = s.jsonp = s.jsonp || "callback",
+                       jsonpCallback = s.jsonpCallback =
+                               jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
+                       url = s.url.replace(jsre, "=" + jsonpCallback + "$1"),
+                       data = s.url == url && typeof(s.data) === "string" ? s.data.replace(jsre, "=" + jsonpCallback + "$1") : s.data;
+                       
+               if ( url == s.url && data == s.data ) {
+                       url = url += (rquery_jsonp.test( url ) ? "&" : "?") + jsonp + "=" + jsonpCallback;
+               }
+               
+               s.url = url;
+               s.data = data;
+               
+               s.dataTypes[0] = "json";
+       }
+       
+});
+
+// Bind transport to json dataType
+jQuery.xhr.bindTransport("json", function(s) {
+
+       if ( s.jsonp ) {
+               
+               // Put callback in place
+               var responseContainer,
+                       jsonpCallback = s.jsonpCallback,
+                       previous = window[ jsonpCallback ];
+                       
+               window [ jsonpCallback ] = function( response ) {
+                       responseContainer = [response];
+               };
+               
+               s.complete = [function() {
+
+                       // Set callback back to previous value
+                       window[ jsonpCallback ] = previous;
+                       
+                       // Call if it was a function and we have a response
+                       if ( previous) {
+                               if ( responseContainer && jQuery.isFunction ( previous ) ) {
+                                       window[ jsonpCallback ] ( responseContainer[0] );
+                               }
+                       } else {
+                               // else, more memory leak avoidance
+                               try{ delete window[ jsonpCallback ]; } catch(e){}
+                       }
+                       
+               }, s.complete ];
+                               
+               // Use data converter to retrieve json after script execution
+               s.dataConverters["script => json"] = function() {
+                       if ( ! responseContainer ) {
+                               jQuery.error("Callback '" + jsonpCallback + "' was not called");
+                       }
+                       return responseContainer[ 0 ];
+               };
+               
+               // Delegate to script transport
+               return "script";
+               
+       }
+
+});
+
+})( jQuery );
diff --git a/src/transports/script.js b/src/transports/script.js
new file mode 100644 (file)
index 0000000..fe38735
--- /dev/null
@@ -0,0 +1,83 @@
+(function( jQuery ) {
+
+// Install text to script executor
+jQuery.extend( true, jQuery.ajaxSettings , {
+
+       accepts: {
+               script: "text/javascript, application/javascript"
+       },
+       
+       autoDataType: {
+               script: /javascript/
+       },
+               
+       dataConverters: {
+               "text => script": jQuery.globalEval
+       }
+} );
+
+// Bind script tag hack transport
+jQuery.xhr.bindTransport("script", function(s) {
+       
+       // Handle cache special case
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       
+       // This transport only deals with cross domain get requests
+       if ( s.crossDomain && s.async && ( s.type === "GET" || ! s.data ) ) {
+               
+               s.global = false;
+               
+               var script,
+                       head = document.getElementsByTagName("head")[0] || document.documentElement;
+               
+               return {
+                       
+                       send: function(_, callback) {
+
+                               script = document.createElement("script");
+
+                               script.async = "async";
+
+                               if ( s.scriptCharset ) {
+                                       script.charset = s.scriptCharset;
+                               }
+                               
+                               script.src = s.url;
+                               
+                               // Attach handlers for all browsers
+                               script.onload = script.onreadystatechange = function(statusText) {
+                                       
+                                       if ( (!script.readyState ||
+                                                       script.readyState === "loaded" || script.readyState === "complete") ) {
+                                                               
+                                               // Handle memory leak in IE
+                                               script.onload = script.onreadystatechange = null;
+                                               
+                                               // Remove the script
+                                               if ( head && script.parentNode ) {
+                                                       head.removeChild( script );
+                                               }
+                                               
+                                               script = undefined;
+                                               
+                                               // Callback & dereference
+                                               callback(statusText ? 0 : 200, statusText || "success");
+                                       }
+                               };
+                               // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
+                               // This arises when a base node is used (#2709 and #4378).
+                               head.insertBefore( script, head.firstChild );
+                       },
+                       
+                       abort: function(statusText) {
+                               if ( script ) {
+                                       script.onload(statusText);
+                               }
+                       }
+               };
+       }
+});
+
+})( jQuery );
diff --git a/src/transports/xhr.js b/src/transports/xhr.js
new file mode 100644 (file)
index 0000000..783ee46
--- /dev/null
@@ -0,0 +1,191 @@
+(function( jQuery ) {
+
+var // Next fake timer id
+       xhrPollingId = jQuery.now(),
+       
+       // Callbacks hashtable
+       xhrs = {},
+
+       // #5280: see end of file
+       xhrUnloadAbortMarker = [];
+
+       
+jQuery.xhr.bindTransport( function( s , determineDataType ) {
+       
+       // Cross domain only allowed if supported through XMLHttpRequest
+       if ( ! s.crossDomain || jQuery.support.cors ) {
+               
+               var callback;
+               
+               return {
+                       
+                       send: function(headers, complete) {
+                               
+                               var xhr = s.xhr(),
+                                       handle;
+                               
+                               // Open the socket
+                               // Passing null username, generates a login popup on Opera (#2865)
+                               if ( s.username ) {
+                                       xhr.open(s.type, s.url, s.async, s.username, s.password);
+                               } else {
+                                       xhr.open(s.type, s.url, s.async);
+                               }
+                               
+                               // Requested-With header
+                               // Not set for crossDomain requests with no content
+                               // (see why at http://trac.dojotoolkit.org/ticket/9486)
+                               // Won't change header if already provided in beforeSend
+                               if ( ! ( s.crossDomain && ! s.hasContent ) && ! headers["x-requested-with"] ) {
+                                       headers["x-requested-with"] = "XMLHttpRequest";
+                               }
+                               
+                               // Need an extra try/catch for cross domain requests in Firefox 3
+                               try {
+                                       
+                                       jQuery.each(headers, function(key,value) {
+                                               xhr.setRequestHeader(key,value);
+                                       });
+                                       
+                               } catch(_) {}
+                               
+                               // Do send the request
+                               try {
+                                       xhr.send( ( s.hasContent && s.data ) || null );
+                               } catch(e) {
+                                       complete(0, "error", "" + e);
+                                       return;
+                               }
+                               
+                               // Listener
+                               callback = function ( abortStatusText ) {
+                                       
+                                       // Was never called and is aborted or complete
+                                       if ( callback && ( abortStatusText || xhr.readyState === 4 ) ) {
+                                       
+                                               // Do not listen anymore
+                                               if (handle) {
+                                                       xhr.onreadystatechange = jQuery.noop;
+                                                       delete xhrs[ handle ];
+                                                       handle = undefined;
+                                               }
+                                               
+                                               callback = 0;
+                                               
+                                               // Get info
+                                               var status, statusText, response, responseHeaders;
+                                                       
+                                               if ( abortStatusText ) {
+                                                       
+                                                       if ( xhr.readyState !== 4 ) {
+                                                               xhr.abort();
+                                                       }
+                                                       
+                                                       // Stop here if unloadAbort
+                                                       if ( abortStatusText === xhrUnloadAbortMarker ) {
+                                                               return;
+                                                       }
+                                                       
+                                                       status = 0;
+                                                       statusText = abortStatusText;
+                                                       
+                                               } else {
+                                                       
+                                                       status = xhr.status;
+                                                       
+                                                       try { // Firefox throws an exception when accessing statusText for faulty cross-domain requests
+                                                               
+                                                               statusText = xhr.statusText;
+                                                               
+                                                       } catch( e ) {
+                                                               
+                                                               statusText = ""; // We normalize with Webkit giving an empty statusText
+                                                               
+                                                       }
+                                                       
+                                                       responseHeaders = xhr.getAllResponseHeaders();
+                                                       
+                                                       // Filter status for non standard behaviours
+                                                       // (so many they seem to be the actual "standard")
+                                                       status =
+                                                               // Opera returns 0 when it should be 304
+                                                               // Webkit returns 0 for failing cross-domain no matter the real status
+                                                               status === 0 ?
+                                                                       (
+                                                                               ! s.crossDomain || statusText ? // Webkit, Firefox: filter out faulty cross-domain requests
+                                                                               (
+                                                                                       responseHeaders ? // Opera: filter out real aborts #6060
+                                                                                       304
+                                                                                       :
+                                                                                       0
+                                                                               )
+                                                                               :
+                                                                               302 // We assume 302 but could be anything cross-domain related
+                                                                       )
+                                                                       :
+                                                                       (
+                                                                               status == 1223 ?        // IE sometimes returns 1223 when it should be 204 (see #1450)
+                                                                                       204
+                                                                                       :
+                                                                                       status
+                                                                       );
+                                                                       
+                                                       // Guess response if needed & update datatype accordingly
+                                                       if ( status >= 200 && status < 300 ) {
+                                                               response = 
+                                                                       determineDataType(
+                                                                               s,
+                                                                               xhr.getResponseHeader("content-type"),
+                                                                               xhr.responseText,
+                                                                               xhr.responseXML );
+                                                       }
+                                               }
+                                               
+                                               // Call complete
+                                               complete(status,statusText,response,responseHeaders);
+                                       }
+                               };
+                               
+                               // if we're in sync mode
+                               // or it's in cache and has been retrieved directly (IE6 & IE7)
+                               // we need to manually fire the callback
+                               if ( ! s.async || xhr.readyState === 4 ) {
+                                       
+                                       callback();
+                                       
+                               } else {
+                                       
+                                       // Listener is externalized to handle abort on unload
+                                       handle = xhrPollingId++;
+                                       xhrs[ handle ] = xhr;
+                                       xhr.onreadystatechange = function() {
+                                               callback();
+                                       };
+                               }                                       
+                       },
+                       
+                       abort: function(statusText) {
+                               if ( callback ) {
+                                       callback(statusText);
+                               }
+                       }
+               };
+       }
+});
+
+// #5280: we need to abort on unload or IE will keep connections alive
+jQuery(window).bind( "unload" , function() {
+       
+       // Abort all pending requests
+       jQuery.each(xhrs, function(_, xhr) {
+               if ( xhr.onreadystatechange ) {
+                       xhr.onreadystatechange( xhrUnloadAbortMarker );
+               }
+       });
+       
+       // Resest polling structure to be safe
+       xhrs = {};
+       
+});
+
+})( jQuery );
index 5a479f2..15446bd 100644 (file)
@@ -4,19 +4,14 @@ var runtil = /Until$/,
        rparentsprev = /^(?:parents|prevUntil|prevAll)/,
        // Note: This RegExp should be improved, or likely pulled from Sizzle
        rmultiselector = /,/,
-       rchild = /^\s*>/,
        isSimple = /^.[^:#\[\.,]*$/,
        slice = Array.prototype.slice,
        POS = jQuery.expr.match.POS;
 
 jQuery.fn.extend({
        find: function( selector ) {
-               // Handle "> div" child selectors and pass them to .children()
-               if ( typeof selector === "string" && rchild.test( selector ) ) {
-                       return this.children( selector.replace( rchild, "" ) );
-               }
-
-               var ret = this.pushStack( "", "find", selector ), length = 0;
+               var ret = this.pushStack( "", "find", selector ),
+                       length = 0;
 
                for ( var i = 0, l = this.length; i < l; i++ ) {
                        length = ret.length;
@@ -65,7 +60,9 @@ jQuery.fn.extend({
                var ret = [], i, l, cur = this[0];
 
                if ( jQuery.isArray( selectors ) ) {
-                       var match, matches = {}, selector, level = 1;
+                       var match, selector,
+                               matches = {},
+                               level = 1;
 
                        if ( cur && selectors.length ) {
                                for ( i = 0, l = selectors.length; i < l; i++ ) {
@@ -231,7 +228,9 @@ jQuery.extend({
        },
        
        dir: function( elem, dir, until ) {
-               var matched = [], cur = elem[dir];
+               var matched = [],
+                       cur = elem[ dir ];
+
                while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
                        if ( cur.nodeType === 1 ) {
                                matched.push( cur );
diff --git a/src/xhr.js b/src/xhr.js
new file mode 100644 (file)
index 0000000..4896e6c
--- /dev/null
@@ -0,0 +1,909 @@
+(function( jQuery ) {
+
+var rquery_xhr = /\?/,
+       rhash = /#.*$/,
+       rheaders = /^(.*?):\s*(.*?)\r?$/mg, // IE leaves an \r character at EOL
+       rnoContent = /^(?:GET|HEAD)$/,
+       rts = /([?&])_=[^&]*/,
+       rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+       
+       sliceFunc = Array.prototype.slice,
+       
+       isFunction = jQuery.isFunction;
+       
+// Creates a jQuery xhr object
+jQuery.xhr = function( _native ) {
+       
+       if ( _native ) {
+               return jQuery.ajaxSettings.xhr();
+       }
+       
+       function reset(force) {
+               
+               // We only need to reset if we went through the init phase
+               // (with the exception of object creation)
+               if ( force || internal ) {
+               
+                       // Reset callbacks lists
+                       callbacksLists = {
+                               success: createCBList(),
+                               error: createCBList(),
+                               complete: createCBList()
+                       };
+                       
+                       // Reset private variables
+                       requestHeaders = {};
+                       responseHeadersString = responseHeaders = internal = done = timeoutTimer = s = undefined;
+                       
+                       // Reset state
+                       xhr.readyState = 0;
+                       sendFlag = 0;
+                       
+                       // Remove responseX fields
+                       for ( var name in xhr ) {
+                               if ( /^response/.test(name) ) {
+                                       delete xhr[name];
+                               }
+                       }
+               }
+       }
+       
+       function init() {
+               
+               var // Options extraction
+               
+                       // Remove hash character (#7531: first for string promotion)
+                       url = s.url = ( "" + s.url ).replace( rhash , "" ),
+                       
+                       // Uppercase the type
+                       type = s.type = s.type.toUpperCase(),
+                       
+                       // Determine if request has content
+                       hasContent = s.hasContent = ! rnoContent.test( type ),
+                       
+                       // Extract dataTypes list
+                       dataType = s.dataType,
+                       dataTypes = s.dataTypes = dataType ? jQuery.trim(dataType).toLowerCase().split(/\s+/) : ["*"],
+                       
+                       // Determine if a cross-domain request is in order
+                       parts = rurl.exec( url.toLowerCase() ),
+                       loc = location,
+                       crossDomain = s.crossDomain = !!( parts && ( parts[1] && parts[1] != loc.protocol || parts[2] != loc.host ) ),
+                       
+                       // Get other options locally
+                       data = s.data,
+                       originalContentType = s.contentType,
+                       prefilters = s.prefilters,
+                       accepts = s.accepts,
+                       headers = s.headers,
+                       
+                       // Other Variables
+                       transportDataType,
+                       i;
+                       
+               // Convert data if not already a string
+               if ( data && s.processData && typeof data != "string" ) {
+                       data = s.data = jQuery.param( data , s.traditional );
+               }
+               
+               // Apply option prefilters
+               for ( i = 0; i < prefilters.length; i++ ) {
+                       prefilters[i](s);
+               }
+               
+               // Get internal
+               internal = selectTransport( s );
+               
+               // Re-actualize url & data
+               url = s.url;
+               data = s.data;
+               
+               // If internal was found
+               if ( internal ) {
+                       
+                       // Get transportDataType
+                       transportDataType = dataTypes[0];
+                       
+                       // More options handling for requests with no content
+                       if ( ! hasContent ) {
+                               
+                               // If data is available, append data to url
+                               if ( data ) {
+                                       url += (rquery_xhr.test(url) ? "&" : "?") + data;
+                               }
+                                                               
+                               // Add anti-cache in url if needed
+                               if ( s.cache === false ) {
+                                       
+                                       var ts = jQuery.now(),
+                                               // try replacing _= if it is there
+                                               ret = url.replace(rts, "$1_=" + ts );
+                                               
+                                       // if nothing was replaced, add timestamp to the end
+                                       url = ret + ((ret == url) ? (rquery_xhr.test(url) ? "&" : "?") + "_=" + ts : "");
+                               }
+                               
+                               s.url = url;
+                       }
+                       
+                       // Set the correct header, if data is being sent
+                       if ( ( data && hasContent ) || originalContentType ) {
+                               requestHeaders["content-type"] = s.contentType;
+                       }
+               
+                       // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                       if ( s.ifModified ) {
+                               if ( jQuery_lastModified[url] ) { 
+                                       requestHeaders["if-modified-since"] = jQuery_lastModified[url];
+                               }
+                               if ( jQuery_etag[url] ) {
+                                       requestHeaders["if-none-match"] = jQuery_etag[url];
+                               }
+                       }
+               
+                       // Set the Accepts header for the server, depending on the dataType
+                       requestHeaders.accept = transportDataType && accepts[ transportDataType ] ?
+                               accepts[ transportDataType ] + ( transportDataType !== "*" ? ", */*; q=0.01" : "" ) :
+                               accepts[ "*" ];
+                               
+                       // Check for headers option
+                       for ( i in headers ) {
+                               requestHeaders[ i.toLowerCase() ] = headers[ i ];
+                       }                       
+               }
+                       
+               callbackContext = s.context || s;
+               globalEventContext = s.context ? jQuery(s.context) : jQuery.event;
+               
+               for ( i in callbacksLists ) {
+                       callbacksLists[i].bind(s[i]);
+               }
+               
+               // Watch for a new set of requests
+               if ( s.global && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger( "ajaxStart" );
+               }
+               
+               done = whenDone;
+       }
+       
+       function whenDone(status, statusText, response, headers) {
+               
+               // Called once
+               done = undefined;
+               
+               // Reset sendFlag
+               sendFlag = 0;
+               
+               // Cache response headers
+               responseHeadersString = headers || "";
+
+               // Clear timeout if it exists
+               if ( timeoutTimer ) {
+                       clearTimeout(timeoutTimer);
+               }
+               
+               var // Reference url
+                       url = s.url,
+                       // and ifModified status
+                       ifModified = s.ifModified,
+                       
+                       // Is it a success?
+                       isSuccess = 0,
+                       // Stored success
+                       success,
+                       // Stored error
+                       error = statusText;
+
+               // If not timeout, force a jQuery-compliant status text
+               if ( statusText != "timeout" ) {
+                       statusText = ( status >= 200 && status < 300 ) ? 
+                               "success" :
+                               ( status === 304 ? "notmodified" : "error" );
+               }
+               
+               // If successful, handle type chaining
+               if ( statusText === "success" || statusText === "notmodified" ) {
+                       
+                       // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+                       if ( ifModified ) {
+                               var lastModified = xhr.getResponseHeader("Last-Modified"),
+                                       etag = xhr.getResponseHeader("Etag");
+                                       
+                               if (lastModified) {
+                                       jQuery_lastModified[url] = lastModified;
+                               }
+                               if (etag) {
+                                       jQuery_etag[url] = etag;
+                               }
+                       }
+                       
+                       if ( ifModified && statusText === "notmodified" ) {
+                               
+                               success = null;
+                               isSuccess = 1;
+                               
+                       } else {
+                               // Chain data conversions and determine the final value
+                               // (if an exception is thrown in the process, it'll be notified as an error)
+                               try {
+                                       
+                                       function checkData(data) {
+                                               if ( data !== undefined ) {
+                                                       var testFunction = s.dataCheckers[srcDataType];
+                                                       if ( isFunction( testFunction ) ) {
+                                                               testFunction(data);
+                                                       }
+                                               }
+                                       }
+                                       
+                                       function convertData (data) {
+                                               var conversionFunction = dataConverters[srcDataType+" => "+destDataType] ||
+                                                               dataConverters["* => "+destDataType],
+                                                       noFunction = ! isFunction( conversionFunction );
+                                               if ( noFunction ) {
+                                                       if ( srcDataType != "text" && destDataType != "text" ) {
+                                                               // We try to put text inbetween
+                                                               var first = dataConverters[srcDataType+" => text"] ||
+                                                                               dataConverters["* => text"],
+                                                                       second = dataConverters["text => "+destDataType] ||
+                                                                               dataConverters["* => "+destDataType],
+                                                                       areFunctions = isFunction( first ) && isFunction( second );
+                                                               if ( areFunctions ) {
+                                                                       conversionFunction = function (data) {
+                                                                               return second( first ( data ) );
+                                                                       };
+                                                               }
+                                                               noFunction = ! areFunctions;
+                                                       }
+                                                       if ( noFunction ) {
+                                                               jQuery.error( "no data converter between " + srcDataType + " and " + destDataType );
+                                                       }
+                                                       
+                                               }
+                                               return conversionFunction(data);
+                                       }
+                                       
+                                       var dataTypes = s.dataTypes,
+                                               i,
+                                               length,
+                                               data = response,
+                                               dataConverters = s.dataConverters,
+                                               srcDataType,
+                                               destDataType,
+                                               responseTypes = s.xhrResponseFields;
+                                               
+                                       for ( i = 0, length = dataTypes.length ; i < length ; i++ ) {
+       
+                                               destDataType = dataTypes[i];
+                                               
+                                               if ( !srcDataType ) { // First time
+                                                       
+                                                       // Copy type
+                                                       srcDataType = destDataType;
+                                                       // Check
+                                                       checkData(data);
+                                                       // Apply dataFilter
+                                                       if ( isFunction( s.dataFilter ) ) {
+                                                               data = s.dataFilter(data, s.dataType);
+                                                               // Recheck data
+                                                               checkData(data);
+                                                       }
+                                                       
+                                               } else { // Subsequent times
+                                                       
+                                                       // handle auto
+                                                       // JULIAN: for reasons unknown to me === doesn't work here
+                                                       if (destDataType == "*") {
+       
+                                                               destDataType = srcDataType;
+                                                               
+                                                       } else if ( srcDataType != destDataType ) {
+                                                               
+                                                               // Convert
+                                                               data = convertData(data);
+                                                               // Copy type & check
+                                                               srcDataType = destDataType;
+                                                               checkData(data);
+                                                               
+                                                       }
+                                                       
+                                               }
+       
+                                               // Copy response into the xhr if it hasn't been already
+                                               var responseDataType,
+                                                       responseType = responseTypes[srcDataType];
+                                               
+                                               if ( responseType ) {
+                                                       
+                                                       responseDataType = srcDataType;
+                                                       
+                                               } else {
+                                                       
+                                                       responseType = responseTypes[ responseDataType = "text" ];
+                                                       
+                                               }
+                                                       
+                                               if ( responseType !== 1 ) {
+                                                       xhr[ "response" + responseType ] = data;
+                                                       responseTypes[ responseType ] = 1;
+                                               }
+                                               
+                                       }
+       
+                                       // We have a real success
+                                       success = data;
+                                       isSuccess = 1;
+                                       
+                               } catch(e) {
+                                       
+                                       statusText = "parsererror";
+                                       error = "" + e;
+                                       
+                               }
+                       }
+                       
+               } else { // if not success, mark it as an error
+                       
+                               error = error || statusText;
+                               
+               }
+                       
+               // Set data for the fake xhr object
+               xhr.status = status;
+               xhr.statusText = statusText;
+               
+               // Keep local copies of vars in case callbacks re-use the xhr
+               var _s = s,
+                       _callbacksLists = callbacksLists,
+                       _callbackContext = callbackContext,
+                       _globalEventContext = globalEventContext;
+                       
+               // Set state if the xhr hasn't been re-used
+               function _setState( value ) {
+                       if ( xhr.readyState && s === _s ) {
+                               setState( value );
+                       }
+               }
+                               
+               // Really completed?
+               if ( status && s.async ) {
+                       setState( 2 );
+                       _setState( 3 );
+               }
+               
+               // We're done
+               _setState( 4 );
+               
+               // Success
+               _callbacksLists.success.fire( isSuccess , _callbackContext , success, statusText, xhr);
+               if ( isSuccess && _s.global ) {
+                       _globalEventContext.trigger( "ajaxSuccess", [xhr, _s, success] );
+               }
+               // Error
+               _callbacksLists.error.fire( ! isSuccess , _callbackContext , xhr, statusText, error);
+               if ( !isSuccess && _s.global ) {
+                       _globalEventContext.trigger( "ajaxError", [xhr, _s, error] );   
+               }
+               // Complete
+               _callbacksLists.complete.fire( 1 , _callbackContext, xhr, statusText);
+               if ( _s.global ) {
+                       _globalEventContext.trigger( "ajaxComplete", [xhr, _s] );
+                       // Handle the global AJAX counter
+                       if ( ! --jQuery.active ) {
+                               jQuery.event.trigger( "ajaxStop" );
+                       }
+               }
+       }
+       
+       // Ready state control
+       function checkState( expected , test ) {
+               if ( expected !== true && ( expected === false || test === false || xhr.readyState !== expected ) ) {
+                       jQuery.error("INVALID_STATE_ERR");
+               }
+       }
+       
+       // Ready state change
+       function setState( value ) {
+               xhr.readyState = value;
+               if ( isFunction( xhr.onreadystatechange ) ) {
+                       xhr.onreadystatechange();
+               }
+       }
+       
+       var // jQuery lists
+               jQuery_lastModified = jQuery.lastModified,
+               jQuery_etag = jQuery.etag,
+               // Options object
+               s,
+               // Callback stuff
+               callbackContext,
+               globalEventContext,
+               callbacksLists,
+               // Headers (they are sent all at once)
+               requestHeaders,
+               // Response headers
+               responseHeadersString,
+               responseHeaders,
+               // Done callback
+               done,
+               // transport
+               internal,
+               // timeout handle
+               timeoutTimer,
+               // The send flag
+               sendFlag,
+               // Fake xhr
+               xhr = {
+                       // state
+                       readyState: 0,
+                       
+                       // Callback
+                       onreadystatechange: null,
+                       
+                       // Open
+                       open: function(type, url, async, username, password) {
+                               
+                               xhr.abort();
+                               reset();
+                               
+                               s = {
+                                       type: type,
+                                       url: url,
+                                       async: async,
+                                       username: username,
+                                       password: password
+                               };
+                               
+                               setState(1);
+                               
+                               return xhr;
+                       },
+                       
+                       // Send
+                       send: function(data, moreOptions) {
+                               
+                               checkState(1 , !sendFlag);
+                               
+                               s.data = data;
+                               
+                               s = jQuery.extend( true,
+                                       {},
+                                       jQuery.ajaxSettings,
+                                       s,
+                                       moreOptions || ( moreOptions === false ? { global: false } : {} ) );
+                                       
+                               if ( moreOptions ) {
+                                       // We force the original context
+                                       // (plain objects used as context get extended)
+                                       s.context = moreOptions.context;
+                               }
+                               
+                               init();
+                               
+                               // If not internal, abort
+                               if ( ! internal ) {
+                                       done( 0 , "transport not found" );
+                                       return false;
+                               }
+                               
+                               // Allow custom headers/mimetypes and early abort
+                               if ( s.beforeSend ) {
+                                       
+                                       var _s = s;
+                                       
+                                       if ( s.beforeSend.call(callbackContext, xhr, s) === false || ! xhr.readyState || _s !== s ) {
+                                               
+                                               // Abort if not done
+                                               if ( xhr.readyState && _s === s ) {
+                                                       xhr.abort();
+                                               }
+       
+                                               // Handle the global AJAX counter
+                                               if ( _s.global && ! --jQuery.active ) {
+                                                       jQuery.event.trigger( "ajaxStop" );
+                                               }
+                                               
+                                               return false;
+                                       }
+                               }
+                               
+                               sendFlag = 1;
+                               
+                               // Send global event
+                               if ( s.global ) {
+                                       globalEventContext.trigger("ajaxSend", [xhr, s]);
+                               }
+                               
+                               // Timeout
+                               if ( s.async && s.timeout > 0 ) {
+                                       timeoutTimer = setTimeout(function(){
+                                               xhr.abort("timeout");
+                                       }, s.timeout);
+                               }
+                               
+                               if ( s.async ) {
+                                       setState(1);
+                               }
+                               
+                               try {
+                                       
+                                       internal.send(requestHeaders, done);
+                                       return xhr;
+                                                                                       
+                               } catch (e) {
+                                       
+                                       if ( done ) {
+                                               
+                                               done(0, "error", "" + e);
+                                               
+                                       } else {
+                                               
+                                               jQuery.error(e);
+                                               
+                                       }
+                               }
+                               
+                               return false;
+                       },
+                       
+                       // Caches the header
+                       setRequestHeader: function(name,value) {
+                               checkState(1, !sendFlag);
+                               requestHeaders[ name.toLowerCase() ] = value;
+                               return xhr;
+                       },
+                       
+                       // Raw string
+                       getAllResponseHeaders: function() {
+                               return xhr.readyState <= 1 ? "" : responseHeadersString;
+                       },
+                       
+                       // Builds headers hashtable if needed
+                       getResponseHeader: function( key ) {
+                               
+                               if ( xhr.readyState <= 1 ) {
+                                       
+                                       return null;
+                                       
+                               }
+                               
+                               if ( responseHeaders === undefined ) {
+                                       
+                                       responseHeaders = {};
+                                       
+                                       if ( typeof responseHeadersString === "string" ) {
+                                               
+                                               var match;
+                                               
+                                               while( ( match = rheaders.exec( responseHeadersString ) ) ) {
+                                                       responseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];
+                                               }
+                                       }
+                               }
+                               return responseHeaders[ key.toLowerCase() ];
+                       },
+                       
+                       // Cancel the request
+                       abort: function(statusText) {
+                               if (internal) {
+                                       internal.abort( statusText || "abort" );
+                               }
+                               xhr.readyState = 0;
+                       }
+               };
+               
+       // Init data (so that we can bind callbacks early
+       reset(1);
+
+       // Install callbacks related methods
+       jQuery.each(callbacksLists, function(name) {
+               var list;
+               xhr[name] = function() {
+                       list = callbacksLists[name];
+                       if ( list ) {
+                               list.bind.apply(list, arguments );
+                       }
+                       return this;
+               };
+       });
+       
+       // Return the xhr emulation
+       return xhr;
+};
+
+// Create a callback list
+function createCBList() {
+       
+       var functors = [],
+               autoFire = 0,
+               fireArgs,
+               list = {
+               
+                       fire: function( flag , context ) {
+                               
+                               // Save info for later bindings
+                               fireArgs = arguments;
+                               
+                               // Remove autoFire to keep bindings in order
+                               autoFire = 0;
+                                       
+                               var args = sliceFunc.call( fireArgs , 2 );
+                                       
+                               // Execute callbacks
+                               while ( flag && functors.length ) {
+                                       flag = functors.shift().apply( context , args ) !== false;
+                               }
+                                       
+                               // Clean if asked to stop
+                               if ( ! flag ) {
+                                       clean();
+                               }
+                                               
+                               // Set autoFire
+                               autoFire = 1;                                   
+                       },
+                       
+                       bind: function() {
+                               
+                               var args = arguments,
+                                       i = 0,
+                                       length = args.length,
+                                       func;
+                               
+                               for ( ; i < length ; i++ ) {
+                                       
+                                       func = args[ i ];
+                                       
+                                       if ( jQuery.isArray(func) ) {
+                                               
+                                               list.bind.apply( list , func );
+                                               
+                                       } else if ( isFunction(func) ) {
+                                               
+                                               // Add if not already in
+                                               if ( ! pos( func ) ) {
+                                                       functors.push( func );
+                                               }
+                                       }
+                               }
+                               
+                               if ( autoFire ) {
+                                       list.fire.apply( list , fireArgs );
+                               }
+                       },
+                       
+                       unbind: function() {
+                               
+                               var i = 0,
+                                       args = arguments,
+                                       length = args.length,
+                                       func,                                   
+                                       position;
+                                       
+                               if ( length ) {
+                                               
+                                       for( ; i < length ; i++ ) {
+                                               func = args[i];
+                                               if ( jQuery.isArray(func) ) {
+                                                       list.unbind.apply(list,func);
+                                               } else if ( isFunction(func) ) {
+                                                       position = pos(func);
+                                                       if ( position ) {
+                                                               functors.splice(position-1,1);
+                                                       }
+                                               }
+                                       }
+                               
+                               } else {
+                                       
+                                       functors = [];
+                               
+                               }
+
+                       }
+                       
+               };
+
+       // Get the index of the functor in the list (1-based)
+       function pos( func ) {
+               for (var i = 0, length = functors.length; i < length && functors[i] !== func; i++) {
+               }
+               return i < length ? ( i + 1 ) : 0;
+       }
+               
+       // Clean the object
+       function clean() {
+               // Empty callbacks list
+               functors = [];
+               // Inhibit methods
+               for (var i in list) {
+                       list[i] = jQuery.noop;
+               }
+       }
+                               
+       return list;
+}
+
+jQuery.extend(jQuery.xhr, {
+       
+       // Add new prefilter
+       prefilter: function (functor) {
+               if ( isFunction(functor) ) {
+                       jQuery.ajaxSettings.prefilters.push( functor );
+               }
+               return this;
+       },
+       
+       // Bind a transport to one or more dataTypes
+       bindTransport: function () {
+               
+               var args = arguments,
+                       i,
+                       start = 0,
+                       length = args.length,
+                       dataTypes = [ "*" ],
+                       functors = [],
+                       functor,
+                       first,
+                       append,
+                       list,
+                       transports = jQuery.ajaxSettings.transports;
+                       
+               if ( length ) {
+                               
+                       if ( ! isFunction( args[ 0 ] ) ) {
+                               
+                               dataTypes = args[ 0 ].toLowerCase().split(/\s+/);
+                               start = 1;
+                               
+                       }
+                       
+                       if ( dataTypes.length && start < length ) {
+                               
+                               for ( i = start; i < length; i++ ) {
+                                       functor = args[i];
+                                       if ( isFunction(functor) ) {
+                                               functors.push( functor );
+                                       }
+                               }
+                                               
+                               if ( functors.length ) {
+                                                       
+                                       jQuery.each ( dataTypes, function( _ , dataType ) {
+                                               
+                                               first = /^\+/.test( dataType );
+                                               
+                                               if (first) {
+                                                       dataType = dataType.substr(1);
+                                               }
+                                               
+                                               if ( dataType !== "" ) {
+                                               
+                                                       append = Array.prototype[ first ? "unshift" : "push" ];
+                                                       
+                                                       list = transports[ dataType ];
+                                       
+                                                       jQuery.each ( functors, function( _ , functor ) {
+                                                                       
+                                                               if ( ! list ) {
+                                                                       
+                                                                       list = transports[ dataType ] = [ functor ];
+                                                                       
+                                                               } else {
+                                                                       
+                                                                       append.call( list , functor );
+                                                               }
+                                                       } );
+                                               }
+                                                                       
+                                       } );
+                               }
+                       }
+               }
+               
+               return this;
+       }
+
+       
+});
+
+// Select a transport given options
+function selectTransport( s ) {
+
+       var dataTypes = s.dataTypes,
+               transportDataType,
+               transportsList,
+               transport,
+               i,
+               length,
+               checked = {},
+               flag;
+               
+       function initSearch( dataType ) {
+
+               flag = transportDataType !== dataType && ! checked[ dataType ];
+               
+               if ( flag ) {
+                       
+                       checked[ dataType ] = 1;
+                       transportDataType = dataType;
+                       transportsList = s.transports[ dataType ];
+                       i = -1;
+                       length = transportsList ? transportsList.length : 0 ;
+               }
+
+               return flag;
+       }
+       
+       initSearch( dataTypes[ 0 ] );
+
+       for ( i = 0 ; ! transport && i <= length ; i++ ) {
+               
+               if ( i === length ) {
+                       
+                       initSearch( "*" );
+                       
+               } else {
+
+                       transport = transportsList[ i ]( s , determineDataType );
+
+                       // If we got redirected to another dataType
+                       // Search there (if not in progress or already tried)
+                       if ( typeof( transport ) === "string" &&
+                               initSearch( transport ) ) {
+
+                               dataTypes.unshift( transport );
+                               transport = 0;
+                       }
+               }
+       }
+
+       return transport;
+}
+       
+// Utility function that handles dataType when response is received
+// (for those transports that can give text or xml responses)
+function determineDataType( s , ct , text , xml ) {
+       
+       var autoDataType = s.autoDataType,
+               type,
+               regexp,
+               dataTypes = s.dataTypes,
+               transportDataType = dataTypes[0],
+               response;
+       
+       // Auto (xml, json, script or text determined given headers)
+       if ( transportDataType === "*" ) {
+
+               for ( type in autoDataType ) {
+                       if ( ( regexp = autoDataType[ type ] ) && regexp.test( ct ) ) {
+                               transportDataType = dataTypes[0] = type;
+                               break;
+                       }
+               }                       
+       } 
+       
+       // xml and parsed as such
+       if ( transportDataType === "xml" &&
+               xml &&
+               xml.documentElement /* #4958 */ ) {
+               
+               response = xml;
+       
+       // Text response was provided
+       } else {
+               
+               response = text;
+               
+               // If it's not really text, defer to dataConverters
+               if ( transportDataType !== "text" ) {
+                       dataTypes.unshift( "text" );
+               }
+               
+       }
+       
+       return response;
+}      
+
+})( jQuery );
diff --git a/test/data/atom+xml.php b/test/data/atom+xml.php
new file mode 100644 (file)
index 0000000..944591a
--- /dev/null
@@ -0,0 +1,4 @@
+<?php header("Content-type: atom+xml") ?>
+<root>
+       <element />
+</root>
\ No newline at end of file
diff --git a/test/data/css.php b/test/data/css.php
new file mode 100644 (file)
index 0000000..9d079e7
--- /dev/null
@@ -0,0 +1,15 @@
+<?php
+error_reporting(0);
+$id = isset ( $_REQUEST['id'] ) ? $_REQUEST['id'] : null;
+$wait = isset( $_REQUEST['wait'] ) ? $_REQUEST['wait'] : null;
+
+if ( $wait ) sleep( $wait );
+
+header("Content-type: text/css");
+
+if ( $id ) {
+       ?>
+       div#<?= $id ?> { margin-left: 27px }
+       <?php
+}
+?>
\ No newline at end of file
diff --git a/test/data/headers.php b/test/data/headers.php
new file mode 100644 (file)
index 0000000..f2c21c0
--- /dev/null
@@ -0,0 +1,20 @@
+<?php
+
+header( "Sample-Header: Hello World" );
+
+$headers = array();
+
+foreach( $_SERVER as $key => $value ) { 
+       
+       if ( substr( $key , 0 , 5 ) == "HTTP_" ) { 
+               
+               $key = str_replace( "_" , "-" , substr( $key , 5) );
+               $headers[ $key ] = $value;
+
+       }
+       
+} 
+
+foreach( explode( "_" , $_GET[ "keys" ] ) as $key ) {
+       echo "$key: " . $headers[ strtoupper( $key ) ] . "\n";
+}
index c06ef4b..b9df4cf 100644 (file)
@@ -1,12 +1,12 @@
-Lorem ipsum dolor sit amet\r
-consectetuer adipiscing elit\r
-Sed lorem leo\r
-lorem leo consectetuer adipiscing elit\r
-Sed lorem leo\r
-rhoncus sit amet\r
-elementum at\r
-bibendum at, eros\r
-Cras at mi et tortor egestas vestibulum\r
-sed Cras at mi vestibulum\r
-Phasellus sed felis sit amet\r
-orci dapibus semper.\r
+Lorem ipsum dolor sit amet
+consectetuer adipiscing elit
+Sed lorem leo
+lorem leo consectetuer adipiscing elit
+Sed lorem leo
+rhoncus sit amet
+elementum at
+bibendum at, eros
+Cras at mi et tortor egestas vestibulum
+sed Cras at mi vestibulum
+Phasellus sed felis sit amet
+orci dapibus semper.
diff --git a/test/data/with_fries_over_jsonp.php b/test/data/with_fries_over_jsonp.php
new file mode 100644 (file)
index 0000000..456aeb3
--- /dev/null
@@ -0,0 +1,7 @@
+<?php
+error_reporting(0);
+$callback = $_REQUEST['callback'];
+$json = $_REQUEST['json'];
+$text = json_encode(file_get_contents(dirname(__FILE__)."/with_fries.xml"));
+echo "$callback($text)";
+?>
index b2840c1..327085c 100644 (file)
-<html>\r
-    <head>\r
-        <script src='../dist/jquery.js' type='text/javascript'></script>\r
-        <style>\r
-       .red {\r
-           background-color: red;\r
-           border: solid 3px red;\r
-       }\r
-        </style>\r
-    </head>\r
-    <body>\r
-        <h2>Change Tests</h2>\r
-        <table>\r
-           <tr>\r
-               <td>\r
-               Change each:\r
-               </td>\r
-               <td>\r
-               <select class='select_test'>\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two'>change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               <select class='select_test'>\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two' selected="selected">change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               </td>\r
-               <td>\r
-               <select class='mselect_test' multiple="multiple">\r
-                   <option value='one'>change me 1</option>\r
-                   <option value='two'>change me 2</option>\r
-                   <option value='three'>change me 3</option>\r
-               </select>\r
-               </td>\r
-               <td>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox1"/>\r
-               <label for="checkbox1">Checkbox 1</label><br/>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox2"/>\r
-               <label for="checkbox2">Checkbox 2</label>\r
-               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox3" disabled="disabled"/>\r
-               <label for="checkbox3">Checkbox 3</label>\r
-               </td>\r
-               </td>\r
-               </td>\r
-               <td>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio1"/>\r
-               <label for="radio1">Radio1</label><br/>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio2"/>\r
-               <label for="radio2">Radio2</label>\r
-               <input type="radio" class="radio_test" name="myradio" id="radio3" disabled="disabled"/>\r
-               <label for="radio3">Radio3</label>\r
-               </td>\r
-               <td>\r
-               <input class="file_test" id="file1" type="file"/>\r
-               <td>\r
-               <input class='test' value='' id='input' size='10' />\r
-               <input class='test' value='test' id='input2' size='10' readonly="readonly" />\r
-               </td>\r
-               <td>\r
-               <textarea rows='2'></textarea>\r
-               </td>\r
-               <td>$(document).bind('change')</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live:</td>\r
-               <td id='select' class="red">SELECT</td>\r
-               <td id='mselect' class="red">MULTI</td>\r
-               <td id='checkbox' class="red">CHECKBOX</td>\r
-               <td id='radio' class="red">RADIO</td>\r
-               <td id='file' class="red">FILE</td>\r
-               <td id='text' class="red">TEXT</td>\r
-               <td id='textarea' class="red">TEXTAREA</td>\r
-               <td id='boundChange' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Bind:</td>\r
-               <td id='selectbind' class="red">SELECT</td>\r
-               <td id='mselectbind' class="red">MULTI</td>\r
-               <td id='checkboxbind' class="red">CHECKBOX</td>\r
-               <td id='radiobind' class="red">RADIO</td>\r
-               <td id='filebind' class="red">FILE</td>\r
-               <td id='textbind' class="red">TEXT</td>\r
-               <td id='textareabind' class="red">TEXTAREA</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Focusin:</td>\r
-               <td id='selectfocus' class="red">SELECT</td>\r
-               <td id='mselectfocus' class="red">MULTI</td>\r
-               <td id='checkboxfocus' class="red">CHECKBOX</td>\r
-               <td id='radiofocus' class="red">RADIO</td>\r
-               <td id='filefocus' class="red">FILE</td>\r
-               <td id='textfocus' class="red">TEXT</td>\r
-               <td id='textareafocus' class="red">TEXTAREA</td>\r
-               <td id='boundFocus' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Focusout:</td>\r
-               <td id='selectblur' class="red">SELECT</td>\r
-               <td id='mselectblur' class="red">MULTI</td>\r
-               <td id='checkboxblur' class="red">CHECKBOX</td>\r
-               <td id='radioblur' class="red">RADIO</td>\r
-               <td id='fileblur' class="red">FILE</td>\r
-               <td id='textblur' class="red">TEXT</td>\r
-               <td id='textareablur' class="red">TEXTAREA</td>\r
-               <td id='boundBlur' class="red">DOCUMENT</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live Focus:</td>\r
-               <td id='selectlfocus' class="red">SELECT</td>\r
-               <td id='mselectlfocus' class="red">MULTI</td>\r
-               <td id='checkboxlfocus' class="red">CHECKBOX</td>\r
-               <td id='radiolfocus' class="red">RADIO</td>\r
-               <td id='filelfocus' class="red">FILE</td>\r
-               <td id='textlfocus' class="red">TEXT</td>\r
-               <td id='textarealfocus' class="red">TEXTAREA</td>\r
-           </tr>\r
-           <tr>\r
-               <td>Live Blur:</td>\r
-               <td id='selectlblur' class="red">SELECT</td>\r
-               <td id='mselectlblur' class="red">MULTI</td>\r
-               <td id='checkboxlblur' class="red">CHECKBOX</td>\r
-               <td id='radiolblur' class="red">RADIO</td>\r
-               <td id='filelblur' class="red">FILE</td>\r
-               <td id='textlblur' class="red">TEXT</td>\r
-               <td id='textarealblur' class="red">TEXTAREA</td>\r
-           </tr>\r
-        </table>\r
-        <h2>Submit Tests</h2>\r
-        <table>\r
-       <tr>\r
-           <td>\r
-               Submit each:\r
-           </td>\r
-           <td>\r
-               <form action="" id="text_submit">\r
-               <input class='test' type='text' value='Key Return To Submit'/>\r
-               </form>\r
-           </td>\r
-           <td>\r
-               <form action="" id="password_submit">\r
-               <input class='test' type='password' value=''/>\r
-               </form>\r
-           </td>\r
-           <td>\r
-               <form action="" id="submit_submit">\r
-               <input type='submit' value="Click Me To Submit" />\r
-               </form>\r
-           </td>\r
-           <td>$(document).bind('submit')</td>\r
-       </tr>\r
-       <tr>\r
-               <td>Results:</td>\r
-               <td id='textSubmit' class="red">TEXT</td>\r
-               <td id='passwordSubmit' class="red">PASSWORD</td>\r
-               <td id='submitSubmit' class="red">BUTTON</td>\r
-               <td id='boundSubmit' class="red">DOCUMENT</td>\r
-       </tr>\r
-        </table>\r
-\r
-       <ul id="log"></ul>\r
-\r
-        <script type='text/javascript'>\r
-       jQuery.fn.addChangeTest = function( id, prevent ) {\r
-               this.bind("focusin", function(){\r
-                       jQuery(id + "focus").blink();\r
-               }).bind("focusout", function(){\r
-                       jQuery(id + "blur").blink();\r
-               });\r
-\r
-               this.bind("focus", function(){\r
-                       jQuery(id + "lfocus").blink();\r
-               }).bind("blur", function(){\r
-                       jQuery(id + "lblur").blink();\r
-               });\r
-\r
-               return this.bind("change", function(e){\r
-                       jQuery(id + "bind").blink();\r
-               }).live("change", function(e){\r
-                       if ( prevent ) {\r
-                               e.preventDefault();\r
-                       }\r
-\r
-                       jQuery(id).blink();\r
-               });\r
-       };\r
-\r
-       jQuery.fn.addSubmitTest = function( id, prevent ) {\r
-               return this.live("submit", function(e){\r
-                       if ( prevent ) {\r
-                               e.preventDefault();\r
-                       }\r
-\r
-                       jQuery(id).blink();\r
-               });\r
-       };\r
-\r
-       jQuery.fn.blink = function(){\r
-               return this.css("backgroundColor","green").css("border","solid 3px green").delay(700).queue(function(next){\r
-                       jQuery(this).css("backgroundColor","");\r
-                       next();\r
-               });\r
-       };\r
-\r
-       $(document).bind("focusin", function() {\r
-               jQuery("#boundFocus").blink();\r
-       });\r
-       \r
-       $(document).bind("focusout", function() {\r
-               jQuery("#boundBlur").blink();\r
-       });\r
-\r
-       $("td.red").live("hover", function(e) {\r
-               if ( e.type === "mouseenter" ) {\r
-                       $(this).css("backgroundColor","green");\r
-               } else {\r
-                       $(this).css("backgroundColor","");\r
-               }\r
-       });\r
-\r
-       $(".select_test").addChangeTest("#select");\r
-       $(".mselect_test").addChangeTest("#mselect");\r
-       $(".checkbox_test").addChangeTest("#checkbox");\r
-       $(".radio_test").addChangeTest("#radio");\r
-       $(".file_test").addChangeTest("#file");\r
-       $('textarea').addChangeTest("#textarea");\r
-       $('#input').addChangeTest("#text");\r
-       $(document).bind("change", function(){\r
-               jQuery("#boundChange").blink();\r
-       });\r
-       \r
-       $("#text_submit").addSubmitTest("#textSubmit", true);\r
-       $("#password_submit").addSubmitTest("#passwordSubmit", true);\r
-       $("#submit_submit").addSubmitTest("#submitSubmit", true);\r
-       $(document).bind("submit", function(){\r
-               jQuery("#boundSubmit").blink();\r
-       });\r
-       \r
-        </script>\r
-    </body>\r
-</html>\r
+<html>
+    <head>
+        <script src='../dist/jquery.js' type='text/javascript'></script>
+        <style>
+       .red {
+           background-color: red;
+           border: solid 3px red;
+       }
+        </style>
+    </head>
+    <body>
+        <h2>Change Tests</h2>
+        <table>
+           <tr>
+               <td>
+               Change each:
+               </td>
+               <td>
+               <select class='select_test'>
+                   <option value='one'>change me 1</option>
+                   <option value='two'>change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               <select class='select_test'>
+                   <option value='one'>change me 1</option>
+                   <option value='two' selected="selected">change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               </td>
+               <td>
+               <select class='mselect_test' multiple="multiple">
+                   <option value='one'>change me 1</option>
+                   <option value='two'>change me 2</option>
+                   <option value='three'>change me 3</option>
+               </select>
+               </td>
+               <td>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox1"/>
+               <label for="checkbox1">Checkbox 1</label><br/>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox2"/>
+               <label for="checkbox2">Checkbox 2</label>
+               <input type="checkbox" class="checkbox_test" name="mycheckbox" id="checkbox3" disabled="disabled"/>
+               <label for="checkbox3">Checkbox 3</label>
+               </td>
+               </td>
+               </td>
+               <td>
+               <input type="radio" class="radio_test" name="myradio" id="radio1"/>
+               <label for="radio1">Radio1</label><br/>
+               <input type="radio" class="radio_test" name="myradio" id="radio2"/>
+               <label for="radio2">Radio2</label>
+               <input type="radio" class="radio_test" name="myradio" id="radio3" disabled="disabled"/>
+               <label for="radio3">Radio3</label>
+               </td>
+               <td>
+               <input class="file_test" id="file1" type="file"/>
+               <td>
+               <input class='test' value='' id='input' size='10' />
+               <input class='test' value='test' id='input2' size='10' readonly="readonly" />
+               </td>
+               <td>
+               <textarea rows='2'></textarea>
+               </td>
+               <td>$(document).bind('change')</td>
+           </tr>
+           <tr>
+               <td>Live:</td>
+               <td id='select' class="red">SELECT</td>
+               <td id='mselect' class="red">MULTI</td>
+               <td id='checkbox' class="red">CHECKBOX</td>
+               <td id='radio' class="red">RADIO</td>
+               <td id='file' class="red">FILE</td>
+               <td id='text' class="red">TEXT</td>
+               <td id='textarea' class="red">TEXTAREA</td>
+               <td id='boundChange' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Bind:</td>
+               <td id='selectbind' class="red">SELECT</td>
+               <td id='mselectbind' class="red">MULTI</td>
+               <td id='checkboxbind' class="red">CHECKBOX</td>
+               <td id='radiobind' class="red">RADIO</td>
+               <td id='filebind' class="red">FILE</td>
+               <td id='textbind' class="red">TEXT</td>
+               <td id='textareabind' class="red">TEXTAREA</td>
+           </tr>
+           <tr>
+               <td>Focusin:</td>
+               <td id='selectfocus' class="red">SELECT</td>
+               <td id='mselectfocus' class="red">MULTI</td>
+               <td id='checkboxfocus' class="red">CHECKBOX</td>
+               <td id='radiofocus' class="red">RADIO</td>
+               <td id='filefocus' class="red">FILE</td>
+               <td id='textfocus' class="red">TEXT</td>
+               <td id='textareafocus' class="red">TEXTAREA</td>
+               <td id='boundFocus' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Focusout:</td>
+               <td id='selectblur' class="red">SELECT</td>
+               <td id='mselectblur' class="red">MULTI</td>
+               <td id='checkboxblur' class="red">CHECKBOX</td>
+               <td id='radioblur' class="red">RADIO</td>
+               <td id='fileblur' class="red">FILE</td>
+               <td id='textblur' class="red">TEXT</td>
+               <td id='textareablur' class="red">TEXTAREA</td>
+               <td id='boundBlur' class="red">DOCUMENT</td>
+           </tr>
+           <tr>
+               <td>Live Focus:</td>
+               <td id='selectlfocus' class="red">SELECT</td>
+               <td id='mselectlfocus' class="red">MULTI</td>
+               <td id='checkboxlfocus' class="red">CHECKBOX</td>
+               <td id='radiolfocus' class="red">RADIO</td>
+               <td id='filelfocus' class="red">FILE</td>
+               <td id='textlfocus' class="red">TEXT</td>
+               <td id='textarealfocus' class="red">TEXTAREA</td>
+           </tr>
+           <tr>
+               <td>Live Blur:</td>
+               <td id='selectlblur' class="red">SELECT</td>
+               <td id='mselectlblur' class="red">MULTI</td>
+               <td id='checkboxlblur' class="red">CHECKBOX</td>
+               <td id='radiolblur' class="red">RADIO</td>
+               <td id='filelblur' class="red">FILE</td>
+               <td id='textlblur' class="red">TEXT</td>
+               <td id='textarealblur' class="red">TEXTAREA</td>
+           </tr>
+        </table>
+        <h2>Submit Tests</h2>
+        <table>
+       <tr>
+           <td>
+               Submit each:
+           </td>
+           <td>
+               <form action="" id="text_submit">
+               <input class='test' type='text' value='Key Return To Submit'/>
+               </form>
+           </td>
+           <td>
+               <form action="" id="password_submit">
+               <input class='test' type='password' value=''/>
+               </form>
+           </td>
+           <td>
+               <form action="" id="submit_submit">
+               <input type='submit' value="Click Me To Submit" />
+               </form>
+           </td>
+           <td>$(document).bind('submit')</td>
+       </tr>
+       <tr>
+               <td>Results:</td>
+               <td id='textSubmit' class="red">TEXT</td>
+               <td id='passwordSubmit' class="red">PASSWORD</td>
+               <td id='submitSubmit' class="red">BUTTON</td>
+               <td id='boundSubmit' class="red">DOCUMENT</td>
+       </tr>
+        </table>
+
+       <ul id="log"></ul>
+
+        <script type='text/javascript'>
+       jQuery.fn.addChangeTest = function( id, prevent ) {
+               this.bind("focusin", function(){
+                       jQuery(id + "focus").blink();
+               }).bind("focusout", function(){
+                       jQuery(id + "blur").blink();
+               });
+
+               this.bind("focus", function(){
+                       jQuery(id + "lfocus").blink();
+               }).bind("blur", function(){
+                       jQuery(id + "lblur").blink();
+               });
+
+               return this.bind("change", function(e){
+                       jQuery(id + "bind").blink();
+               }).live("change", function(e){
+                       if ( prevent ) {
+                               e.preventDefault();
+                       }
+
+                       jQuery(id).blink();
+               });
+       };
+
+       jQuery.fn.addSubmitTest = function( id, prevent ) {
+               return this.live("submit", function(e){
+                       if ( prevent ) {
+                               e.preventDefault();
+                       }
+
+                       jQuery(id).blink();
+               });
+       };
+
+       jQuery.fn.blink = function(){
+               return this.css("backgroundColor","green").css("border","solid 3px green").delay(700).queue(function(next){
+                       jQuery(this).css("backgroundColor","");
+                       next();
+               });
+       };
+
+       $(document).bind("focusin", function() {
+               jQuery("#boundFocus").blink();
+       });
+       
+       $(document).bind("focusout", function() {
+               jQuery("#boundBlur").blink();
+       });
+
+       $("td.red").live("hover", function(e) {
+               if ( e.type === "mouseenter" ) {
+                       $(this).css("backgroundColor","green");
+               } else {
+                       $(this).css("backgroundColor","");
+               }
+       });
+
+       $(".select_test").addChangeTest("#select");
+       $(".mselect_test").addChangeTest("#mselect");
+       $(".checkbox_test").addChangeTest("#checkbox");
+       $(".radio_test").addChangeTest("#radio");
+       $(".file_test").addChangeTest("#file");
+       $('textarea').addChangeTest("#textarea");
+       $('#input').addChangeTest("#text");
+       $(document).bind("change", function(){
+               jQuery("#boundChange").blink();
+       });
+       
+       $("#text_submit").addSubmitTest("#textSubmit", true);
+       $("#password_submit").addSubmitTest("#passwordSubmit", true);
+       $("#submit_submit").addSubmitTest("#submitSubmit", true);
+       $(document).bind("submit", function(){
+               jQuery("#boundSubmit").blink();
+       });
+       
+        </script>
+    </body>
+</html>
index 03e1d97..238b7d5 100644 (file)
        <script src="../src/manipulation.js"></script>
        <script src="../src/css.js"></script>
        <script src="../src/ajax.js"></script>
+       <script src="../src/xhr.js"></script>
+       <script src="../src/transports/jsonp.js"></script>
+       <script src="../src/transports/script.js"></script>
+       <script src="../src/transports/xhr.js"></script>
        <script src="../src/effects.js"></script>
        <script src="../src/offset.js"></script>
        <script src="../src/dimensions.js"></script>
@@ -260,6 +264,9 @@ Z</textarea>
                        <div id="slidetogglein" class='chain test'>slideToggleIn<div>slideToggleIn</div></div>
                        <div id="slidetoggleout" class='chain test out'>slideToggleOut<div>slideToggleOut</div></div>
 
+                       <div id="fadetogglein" class='chain test'>fadeToggleIn<div>fadeToggleIn</div></div>
+      <div id="fadetoggleout" class='chain test out'>fadeToggleOut<div>fadeToggleOut</div></div>
+
                        <div id="fadeto" class='chain test'>fadeTo<div>fadeTo</div></div>
                </div>
 
index 2ded127..35c0302 100644 (file)
@@ -38,6 +38,216 @@ test("jQuery.ajax() - success callbacks", function() {
        });
 });
 
+test("jQuery.ajax() - success callbacks - (url, options) syntax", function() {
+       expect( 8 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+                       start();
+               }).ajaxSend(function(){
+                       ok( true, "ajaxSend" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete" );
+               }).ajaxError(function(){
+                       ok( false, "ajaxError" );
+               }).ajaxSuccess(function(){
+                       ok( true, "ajaxSuccess" );
+               });
+
+               jQuery.ajax( url("data/name.html") , {
+                       beforeSend: function(){ ok(true, "beforeSend"); },
+                       success: function(){ ok(true, "success"); },
+                       error: function(){ ok(false, "error"); },
+                       complete: function(){ ok(true, "complete"); }
+               });
+       }, 13);
+});
+
+test("jQuery.ajax() - success/error callbacks (remote)", function() {
+       
+       var supports = jQuery.support.cors;
+       
+       expect( supports ? 9 : 6 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+                       start();
+               }).ajaxSend(function(){
+                       ok( supports , "ajaxSend" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete" );
+               }).ajaxError(function(){
+                       ok( ! supports, "ajaxError" );
+               }).ajaxSuccess(function(){
+                       ok( supports, "ajaxSuccess" );
+               });
+
+               jQuery.ajax({
+                       // JULIAN TODO: Get an url especially for jQuery
+                       url: "http://rockstarapps.com/test.php",
+                       dataType: "text",
+                       beforeSend: function(){ ok(supports, "beforeSend"); },
+                       success: function( val ){ ok(supports, "success"); ok(supports && val.length, "data received"); },
+                       error: function(_ , a , b ){ ok(!supports, "error"); },
+                       complete: function(){ ok(true, "complete"); }
+               });
+       }, 13);
+});
+
+test("jQuery.ajax() - success callbacks (late binding)", function() {
+       expect( 8 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+                       start();
+               }).ajaxSend(function(){
+                       ok( true, "ajaxSend" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete" );
+               }).ajaxError(function(){
+                       ok( false, "ajaxError" );
+               }).ajaxSuccess(function(){
+                       ok( true, "ajaxSuccess" );
+               });
+
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       beforeSend: function(){ ok(true, "beforeSend"); }
+               })
+                       .complete(function(){ ok(true, "complete"); })
+                       .success(function(){ ok(true, "success"); })
+                       .error(function(){ ok(false, "error"); });
+       }, 13);
+});
+
+test("jQuery.ajax() - success callbacks (oncomplete binding)", function() {
+       expect( 8 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+               }).ajaxSend(function(){
+                       ok( true, "ajaxSend" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete" );
+               }).ajaxError(function(){
+                       ok( false, "ajaxError" );
+               }).ajaxSuccess(function(){
+                       ok( true, "ajaxSuccess" );
+               });
+
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       beforeSend: function(){ ok(true, "beforeSend"); },
+                       complete: function(xhr) {
+                               xhr
+                               .complete(function(){ ok(true, "complete"); })
+                               .success(function(){ ok(true, "success"); })
+                               .error(function(){ ok(false, "error"); })
+                               .complete(function(){ start(); });
+                       }
+               })
+       }, 13);
+});
+
+test("jQuery.ajax() - success callbacks (very late binding)", function() {
+       expect( 8 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+               }).ajaxSend(function(){
+                       ok( true, "ajaxSend" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete" );
+               }).ajaxError(function(){
+                       ok( false, "ajaxError" );
+               }).ajaxSuccess(function(){
+                       ok( true, "ajaxSuccess" );
+               });
+
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       beforeSend: function(){ ok(true, "beforeSend"); },
+                       complete: function(xhr) {
+                               setTimeout (function() {
+                                       xhr
+                                       .complete(function(){ ok(true, "complete"); })
+                                       .success(function(){ ok(true, "success"); })
+                                       .error(function(){ ok(false, "error"); })
+                                       .complete(function(){ start(); });
+                               },100);
+                       }
+               })
+       }, 13);
+});
+
+test("jQuery.ajax() - success callbacks (order)", function() {
+       expect( 1 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+       
+       var testString = "";
+
+       setTimeout(function(){
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       success: function( _1 , _2 , xhr ) {
+                               xhr.success(function() {
+                                       xhr.success(function() {
+                                               testString += "E";
+                                       });
+                                       testString += "D";
+                               });
+                               testString += "A";
+                       },
+                       complete: function() {
+                               strictEqual(testString, "ABCDE", "Proper order");
+                               start();
+                       }
+               }).success(function() {
+                       testString += "B";
+               }).success(function() {
+                       testString += "C";
+               });
+       }, 13);
+});
+
 test("jQuery.ajax() - error callbacks", function() {
        expect( 8 );
        stop();
@@ -68,9 +278,45 @@ test("jQuery.ajax() - error callbacks", function() {
        });
 });
 
+test(".ajax() - headers" , function() {
+
+       expect( 2 );
+       
+       stop();
+       
+       var requestHeaders = {
+               siMPle: "value",
+               "SometHing-elsE": "other value",
+               OthEr: "something else"
+               },
+               list = [],
+               i;
+               
+       for( i in requestHeaders ) {
+               list.push( i );
+       }
+       
+       jQuery.ajax(url("data/headers.php?keys="+list.join( "_" ) ), {
+               headers: requestHeaders,
+               success: function( data , _ , xhr ) {
+                       var tmp = [];
+                       for ( i in requestHeaders ) {
+                               tmp.push( i , ": " , requestHeaders[ i ] , "\n" );
+                       }
+                       tmp = tmp.join( "" );
+                       
+                       equals( data , tmp , "Headers were sent" );
+                       equals( xhr.getResponseHeader( "Sample-Header" ) , "Hello World" , "Sample header received" );
+                       start();
+               },
+               error: function(){ ok(false, "error"); }
+       });
+               
+});
+
 test(".ajax() - hash", function() {
        expect(3);
-
+       
        jQuery.ajax({
                url: "data/name.html#foo",
                beforeSend: function( xhr, settings ) {
@@ -78,15 +324,15 @@ test(".ajax() - hash", function() {
                        return false;
                }
        });
-
+       
        jQuery.ajax({
                url: "data/name.html?abc#foo",
                beforeSend: function( xhr, settings ) {
-                       equals(settings.url, "data/name.html?abc", "Make sure that the URL is trimmed.");
+               equals(settings.url, "data/name.html?abc", "Make sure that the URL is trimmed.");
                        return false;
                }
        });
-
+       
        jQuery.ajax({
                url: "data/name.html?abc#foo",
                data: { "test": 123 },
@@ -100,7 +346,7 @@ test(".ajax() - hash", function() {
 test(".ajax() - 304", function() {
        expect( 1 );
        stop();
-
+       
        jQuery.ajax({
                url: url("data/notmodified.php"),
                success: function(){ ok(true, "304 ok"); },
@@ -137,7 +383,7 @@ test(".load()) - 404 error callbacks", function() {
 });
 
 test("jQuery.ajax() - abort", function() {
-       expect( 6 );
+       expect( 8 );
        stop();
 
        jQuery('#foo').ajaxStart(function(){
@@ -157,7 +403,140 @@ test("jQuery.ajax() - abort", function() {
                complete: function(){ ok(true, "complete"); }
        });
 
+       equals( xhr.readyState, 1, "XHR readyState indicates successful dispatch" );
+
        xhr.abort();
+       equals( xhr.readyState, 0, "XHR readyState indicates successful abortion" );
+});
+
+test("jQuery.ajax() - readyState (success)", function() {
+       expect( 1 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+       
+       var control = "";
+
+       setTimeout(function(){
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       beforeSend: function( xhr ) {
+                               xhr.onreadystatechange = function() {
+                                       control += xhr.readyState;
+                               }
+                       },
+                       complete: function(){ 
+                               setTimeout( function() {
+                                       equals( control , "1234" , "onreadystatechange was properly called" );
+                               }, 13 );
+                               start();
+                       }
+               });
+       }, 13);
+});
+
+test("jQuery.ajax() - readyState (abort)", function() {
+       expect( 2 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+       
+       var control = "";
+
+       setTimeout(function(){
+
+               jQuery.ajaxSetup({ timeout: 500 });
+
+               jQuery.ajax({
+                       url: url("data/name.php?wait=5"),
+                       beforeSend: function( xhr ) {
+                               xhr.onreadystatechange = function() {
+                                       control += xhr.readyState;
+                               }
+                       },
+                       complete: function( xhr ){ 
+                               setTimeout( function() {
+                                       equals( control , "14" , "onreadystatechange was properly called" );
+                                       equals( xhr.readyState, 0 , "readyState is 0" );
+                               }, 13 );
+                               start();
+                       }
+               });
+       }, 13);
+});
+
+test("jQuery.xhr() - reuse", function() {
+       expect( 15 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+       
+       var number = 0;
+       
+       setTimeout(function(){
+               jQuery('#foo').ajaxStart(function(){
+                       ok( true, "ajaxStart" );
+               }).ajaxStop(function(){
+                       ok( true, "ajaxStop" );
+                       start();
+               }).ajaxSend(function(){
+                       number++;
+                       ok( true, "ajaxSend (" + number +")" );
+               }).ajaxComplete(function(){
+                       ok( true, "ajaxComplete (" + number +")" );
+               }).ajaxError(function(){
+                       ok( false, "ajaxError (" + number +")" );
+               }).ajaxSuccess(function(){
+                       ok( true, "ajaxSuccess (" + number +")" );
+               });
+
+               jQuery.ajax({
+                       url: url("data/name.html"),
+                       beforeSend: function(){ ok(true, "beforeSend (1)"); },
+                       success: function( _1 , _2 , xhr ){
+                               ok(true, "success (1)");
+                               xhr.complete(function() {
+                                       ok(true, "complete (1bis)"); 
+                               });
+                               xhr.open( "GET", url("data/name.html") );
+                               xhr.success( function(){ ok(true, "beforeSend (2)"); } )
+                               xhr.send( null, {
+                                       success: function(){ ok(true, "success (2)"); },
+                                       error: function(){ ok(false, "error (2)"); },
+                                       complete: function(){ ok(true, "complete (2)"); }
+                               } );
+                       },
+                       error: function(){ ok(false, "error (1)"); },
+                       complete: function(){ ok(true, "complete (1)"); }
+               });
+       }, 13);
+});
+
+test("jQuery.xhr() - early binding", function() {
+       expect( 2 );
+
+       jQuery.ajaxSetup({ timeout: 0 });
+
+       stop();
+       
+       jQuery.xhr()
+               .success( function(){ ok(true, "success"); } )
+               .error( function(){ ok(false, "error"); } )
+               .complete( function(){ ok(true, "complete"); start(); } )
+               .open( "GET", url("data/name.html") )
+               .send();
+});
+
+test("jQuery.xhr() - get native implementation", function() {
+       
+       var xhr = jQuery.xhr(true);
+       
+       ok( xhr.readyState !== undefined , "implements XMLHttpRequest" );
+       ok( ! jQuery.isFunction( xhr.success ) , "is not jQuery's abstraction" );
+       
 });
 
 test("Ajax events with context", function() {
@@ -274,6 +653,34 @@ test("jQuery.ajax() - disabled globals", function() {
        });
 });
 
+test("jQuery.xhr() - disabled globals through xhr.send(data , false)", function() {
+       expect( 2 );
+       stop();
+
+       jQuery('#foo').ajaxStart(function(){
+               ok( false, "ajaxStart" );
+       }).ajaxStop(function(){
+               ok( false, "ajaxStop" );
+       }).ajaxSend(function(){
+               ok( false, "ajaxSend" );
+       }).ajaxComplete(function(){
+               ok( false, "ajaxComplete" );
+       }).ajaxError(function(){
+               ok( false, "ajaxError" );
+       }).ajaxSuccess(function(){
+               ok( false, "ajaxSuccess" );
+       });
+
+       jQuery.xhr()
+               .success(function(){ ok(true, "success"); })
+               .error(function(){ ok(false, "error"); })
+               .complete(function(){
+                 ok(true, "complete");
+                 setTimeout(function(){ start(); }, 13);
+               })
+               .open("GET", url("data/name.html")).send(undefined, false);
+});
+
 test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", function() {
        expect(3);
        stop();
@@ -289,6 +696,47 @@ test("jQuery.ajax - xml: non-namespace elements inside namespaced elements", fun
        });
 });
 
+test("jQuery.ajax - xml: non-namespace elements inside namespaced elements (over JSONP)", function() {
+       expect(3);
+       stop();
+       jQuery.ajax({
+         url: url("data/with_fries_over_jsonp.php"),
+         dataType: "jsonp xml",
+         success: function(resp) {
+               equals( jQuery("properties", resp).length, 1, 'properties in responseXML' );
+               equals( jQuery("jsconf", resp).length, 1, 'jsconf in responseXML' );
+               equals( jQuery("thing", resp).length, 2, 'things in responseXML' );
+               start();
+         }
+       });
+});
+
+test("jQuery.ajax - HEAD requests", function() {
+       expect(2);
+
+       stop();
+       jQuery.ajax({
+               url: url("data/name.html"),
+               type: "HEAD",
+               success: function(data, status, xhr){
+                       var h = xhr.getAllResponseHeaders();
+                       ok( /Date/i.test(h), 'No Date in HEAD response' );
+                       
+                       jQuery.ajax({
+                               url: url("data/name.html"),
+                               data: { whip_it: "good" },
+                               type: "HEAD",
+                               success: function(data, status, xhr){
+                                       var h = xhr.getAllResponseHeaders();
+                                       ok( /Date/i.test(h), 'No Date in HEAD response with data' );
+                                       start();
+                               }
+                       });
+               }
+       });
+
+});
+
 test("jQuery.ajax - beforeSend", function() {
        expect(1);
        stop();
@@ -330,6 +778,27 @@ test("jQuery.ajax - beforeSend, cancel request (#2688)", function() {
        ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
 });
 
+test("jQuery.ajax - beforeSend, cancel request manually", function() {
+       expect(2);
+       var request = jQuery.ajax({
+               url: url("data/name.html"),
+               beforeSend: function(xhr) {
+                       ok( true, "beforeSend got called, canceling" );
+                       xhr.abort();
+               },
+               success: function() {
+                       ok( false, "request didn't get canceled" );
+               },
+               complete: function() {
+                       ok( false, "request didn't get canceled" );
+               },
+               error: function() {
+                       ok( false, "request didn't get canceled" );
+               }
+       });
+       ok( request === false, "canceled request must return false instead of XMLHttpRequest instance" );
+});
+
 window.foobar = null;
 window.testFoo = undefined;
 
@@ -427,7 +896,7 @@ test("jQuery.param()", function() {
        equals( jQuery.param({"foo": {"bar": []} }), "foo%5Bbar%5D=", "Empty array param" );
        equals( jQuery.param({"foo": {"bar": [], foo: 1} }), "foo%5Bbar%5D=&foo%5Bfoo%5D=1", "Empty array param" );
        equals( jQuery.param({"foo": {"bar": {}} }), "foo%5Bbar%5D=", "Empty object param" );
-       
+
        jQuery.ajaxSetup({ traditional: true });
        
        var params = {foo:"bar", baz:42, quux:"All your base are belong to us"};
@@ -681,10 +1150,10 @@ test("jQuery.getScript(String, Function) - no callback", function() {
 });
 
 test("jQuery.ajax() - JSONP, Local", function() {
-       expect(8);
+       expect(9);
 
        var count = 0;
-       function plus(){ if ( ++count == 8 ) start(); }
+       function plus(){ if ( ++count == 9 ) start(); }
 
        stop();
 
@@ -799,14 +1268,26 @@ test("jQuery.ajax() - JSONP, Local", function() {
                        plus();
                }
        });
+
+       //#7578
+       jQuery.ajax({
+               url: "data/jsonp.php",
+               dataType: "jsonp",
+               beforeSend: function(){
+                       strictEqual( this.cache, false, "cache must be false on JSON request" );
+                       plus();
+                       return false;
+               }
+       });
 });
 
-test("JSONP - Custom JSONP Callback", function() {
+test("jQuery.ajax() - JSONP - Custom JSONP Callback", function() {
        expect(1);
        stop();
 
        window.jsonpResults = function(data) {
                ok( data.data, "JSON results returned (GET, custom callback function)" );
+               window.jsonpResults = undefined;
                start();
        };
 
@@ -903,7 +1384,7 @@ test("jQuery.ajax() - script, Remote with POST", function() {
        expect(3);
 
        var base = window.location.href.replace(/[^\/]*$/, "");
-
+       
        stop();
 
        jQuery.ajax({
@@ -993,6 +1474,30 @@ test("jQuery.ajax() - json by content-type", function() {
        });
 });
 
+test("jQuery.ajax() - json by content-type disabled with options", function() {
+       expect(6);
+
+       stop();
+
+       jQuery.ajax({
+               url: url("data/json.php"),
+               data: { header: "json", json: "array" },
+               autoDataType: {
+                       json: false
+               },
+               success: function( text ) {
+                       equals( typeof text , "string" , "json wasn't auto-determined" );
+                       var json = this.dataConverters["text => json"]( text );
+                       ok( json.length >= 2, "Check length");
+                       equals( json[0].name, 'John', 'Check JSON: first, name' );
+                       equals( json[0].age, 21, 'Check JSON: first, age' );
+                       equals( json[1].name, 'Peter', 'Check JSON: second, name' );
+                       equals( json[1].age, 25, 'Check JSON: second, age' );
+                       start();
+               }
+       });
+});
+
 test("jQuery.getJSON(String, Hash, Function) - JSON array", function() {
        expect(5);
        stop();
@@ -1250,7 +1755,7 @@ test("jQuery.ajax - If-Modified-Since support", function() {
                                                ok(data == null, "response body should be empty")
                                        }
                                        start();
-                               },
+                       },
                                error: function() {
                                        // Do this because opera simply refuses to implement 304 handling :(
                                        // A feature-driven way of detecting this would be appreciated
@@ -1258,10 +1763,11 @@ test("jQuery.ajax - If-Modified-Since support", function() {
                                        ok(jQuery.browser.opera, "error");
                                        ok(jQuery.browser.opera, "error");
                                        start();
-                               }
+                       }
                        });
                },
                error: function() {
+                       equals(false, "error");
                        // Do this because opera simply refuses to implement 304 handling :(
                        // A feature-driven way of detecting this would be appreciated
                        // See: http://gist.github.com/599419
@@ -1296,8 +1802,8 @@ test("jQuery.ajax - Etag support", function() {
                                                ok(data == null, "response body should be empty")
                                        }
                                        start();
-                               },
-                               error: function() {
+                       },
+                       error: function() {
                                        // Do this because opera simply refuses to implement 304 handling :(
                                        // A feature-driven way of detecting this would be appreciated
                                        // See: http://gist.github.com/599419
@@ -1317,11 +1823,58 @@ test("jQuery.ajax - Etag support", function() {
        });
 });
 
+test("jQuery ajax - failing cross-domain", function() {
+
+       expect( 2 );
+       
+       stop();
+       
+       var i = 2;
+       
+       jQuery.ajax({
+               url: 'http://somewebsitethatdoesnotexist.com',
+               success: function(){ ok( false , "success" ); },
+               error: function(xhr,_,e){ ok( true , "file not found: " + xhr.status + " => " + e ); },
+               complete: function() { if ( ! --i ) start(); }
+       });
+       
+       jQuery.ajax({
+               url: 'http://www.google.com',
+               success: function(){ ok( false , "success" ); },
+               error: function(xhr,_,e){ ok( true , "access denied: " + xhr.status + " => " + e ); },
+               complete: function() { if ( ! --i ) start(); }
+       });
+       
+});
+
+test("jQuery ajax - atom+xml", function() {
+
+       stop();
+       
+       jQuery.ajax({
+               url: url( 'data/atom+xml.php' ),
+               success: function(){ ok( true , "success" ); },
+               error: function(){ ok( false , "error" ); },
+               complete: function() { start(); }
+       });
+       
+});
+
 test("jQuery.ajax - active counter", function() {
-    ok( jQuery.ajax.active == 0, "ajax active counter should be zero: " + jQuery.ajax.active );
+    ok( jQuery.active == 0, "ajax active counter should be zero: " + jQuery.active );
 });
 
+test( "jQuery.ajax - Location object as url (#7531)", 1, function () {
+       var success = false;
+       try {
+               var xhr = jQuery.ajax({ url: window.location });
+               success = true;
+               xhr.abort();
+       } catch (e) {}
+
+       ok( success, "document.location did not generate exception" );
+});
 
 }
 
-//}
+//}
\ No newline at end of file
index c6007aa..f9506b3 100644 (file)
@@ -3,8 +3,33 @@ module("attributes");
 var bareObj = function(value) { return value; };
 var functionReturningObj = function(value) { return (function() { return value; }); };
 
+test("jQuery.props: itegrity test", function() {
+  
+  expect(1);
+  
+  //  This must be maintained and equal jQuery.props
+  //  Ensure that accidental or erroneous property 
+  //  overwrites don't occur
+  //  This is simply for better code coverage and future proofing. 
+  var propsShouldBe = {
+    "for": "htmlFor",
+    "class": "className",
+    readonly: "readOnly",
+    maxlength: "maxLength",
+    cellspacing: "cellSpacing",
+    rowspan: "rowSpan",
+    colspan: "colSpan",
+    tabindex: "tabIndex",
+    usemap: "useMap",
+    frameborder: "frameBorder"
+  };
+  
+  same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check");
+
+});
+
 test("attr(String)", function() {
-       expect(30);
+       expect(37);
 
        // This one sometimes fails randomly ?!
        equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
@@ -65,6 +90,16 @@ test("attr(String)", function() {
 
        ok( jQuery("<div/>").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." );
        ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." );
+
+       equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." );
+
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
+               strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." );
+       });
 });
 
 if ( !isLocal ) {
@@ -98,7 +133,7 @@ test("attr(Hash)", function() {
 });
 
 test("attr(String, Object)", function() {
-       expect(24);
+       expect(30);
 
        var div = jQuery("div").attr("foo", "bar"),
                fail = false;
@@ -132,6 +167,25 @@ test("attr(String, Object)", function() {
        jQuery("#name").attr('maxLength', '10');
        equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' );
 
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       jQuery.each( [document, obj, "#firstp"], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" );
+               equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." );
+       });
+       jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" );
+               strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." );
+       });
+       //cleanup
+       jQuery.each( [document, "#firstp"], function( i, ele ) {
+               jQuery( ele ).removeAttr("nonexisting");
+       });
+
        var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
                td = table.find('td:first');
        td.attr("rowspan", "2");
@@ -302,8 +356,26 @@ test("attr('tabindex', value)", function() {
 });
 
 test("removeAttr(String)", function() {
-       expect(1);
+       expect(7);
        equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" );
+
+       var attributeNode = document.createAttribute("irrelevant"),
+               commentNode = document.createComment("some comment"),
+               textNode = document.createTextNode("some text"),
+               obj = {};
+       //removeAttr only really removes on DOM element nodes handle all other seperatyl
+       strictEqual( jQuery( "#firstp" ).attr( "nonexisting", "foo" ).removeAttr( "nonexisting" )[0].nonexisting, undefined, "removeAttr works correctly on DOM element nodes" );
+
+       jQuery.each( [document, obj], function( i, ele ) {
+               var $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+               strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+       });
+       jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
+               $ele = jQuery( ele );
+               $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+               strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+       });
 });
 
 test("val()", function() {
@@ -512,7 +584,7 @@ test("addClass(Function)", function() {
 });
 
 test("addClass(Function) with incoming value", function() {
-       expect(41);
+       expect(45);
 
        var div = jQuery("div"), old = div.map(function(){
                return jQuery(this).attr("class");
@@ -585,7 +657,7 @@ test("removeClass(Function) - simple", function() {
 });
 
 test("removeClass(Function) with incoming value", function() {
-       expect(41);
+       expect(45);
 
        var $divs = jQuery('div').addClass("test"), old = $divs.map(function(){
                return jQuery(this).attr("class");
@@ -717,7 +789,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
 });
 
 test("addClass, removeClass, hasClass", function() {
-       expect(14);
+       expect(17);
  
        var jq = jQuery("<p>Hi</p>"), x = jq[0];
  
@@ -737,12 +809,14 @@ test("addClass, removeClass, hasClass", function() {
        ok( jq.hasClass("hi"), "Check has1" );
        ok( jq.hasClass("bar"), "Check has2" );
  
-       var jq = jQuery("<p class='class1\nclass2\tcla.ss3\n'></p>");
-       ok( jq.hasClass("class1"), "Check hasClass with carriage return" );
-       ok( jq.is(".class1"), "Check is with carriage return" );
+       var jq = jQuery("<p class='class1\nclass2\tcla.ss3\n\rclass4'></p>");
+       ok( jq.hasClass("class1"), "Check hasClass with line feed" );
+       ok( jq.is(".class1"), "Check is with line feed" );
        ok( jq.hasClass("class2"), "Check hasClass with tab" );
        ok( jq.is(".class2"), "Check is with tab" );
        ok( jq.hasClass("cla.ss3"), "Check hasClass with dot" );
+       ok( jq.hasClass("class4"), "Check hasClass with carriage return" );
+       ok( jq.is(".class4"), "Check is with carriage return" );
  
        jq.removeClass("class2");
        ok( jq.hasClass("class2")==false, "Check the class has been properly removed" );
@@ -750,4 +824,6 @@ test("addClass, removeClass, hasClass", function() {
        ok( jq.hasClass("cla.ss3"), "Check the dotted class has not been removed" );
        jq.removeClass("cla.ss3");
        ok( jq.hasClass("cla.ss3")==false, "Check the dotted class has been removed" );
+       jq.removeClass("class4");
+       ok( jq.hasClass("class4")==false, "Check the class has been properly removed" );
 });
index 7ef2ad7..7057783 100644 (file)
@@ -547,15 +547,15 @@ test("toArray()", function() {
 })
 
 test("get(Number)", function() {
-       expect(1);
+       expect(2);
        equals( jQuery("p").get(0), document.getElementById("firstp"), "Get A Single Element" );
+       strictEqual( jQuery("#firstp").get(1), undefined, "Try get with index larger elements count" );
 });
 
 test("get(-Number)",function() {
-       expect(1);
-       equals( jQuery("p").get(-1),
-               document.getElementById("first"),
-               "Get a single element with negative index" )
+       expect(2);
+       equals( jQuery("p").get(-1), document.getElementById("first"), "Get a single element with negative index" );
+       strictEqual( jQuery("#firstp").get(-2), undefined, "Try get with index negative index larger then elements count" );
 })
 
 test("each(Function)", function() {
index 8a49096..cddd902 100644 (file)
@@ -1,7 +1,7 @@
 module("css");
 
 test("css(String|Hash)", function() {
-       expect(33);
+       expect(41);
 
        equals( jQuery('#main').css("display"), 'block', 'Check for css property "display"');
 
@@ -11,6 +11,26 @@ test("css(String|Hash)", function() {
        jQuery('#nothiddendiv').css({display: 'block'});
        ok( jQuery('#nothiddendiv').is(':visible'), 'Modified CSS display: Assert element is visible');
 
+       var div = jQuery( "<div>" );
+
+       // These should be "auto" (or some better value)
+       // temporarily provide "0px" for backwards compat
+       equals( div.css("width"), "0px", "Width on disconnected node." );
+       equals( div.css("height"), "0px", "Height on disconnected node." );
+
+       div.css({ width: 4, height: 4 });
+
+       equals( div.css("width"), "4px", "Width on disconnected node." );
+       equals( div.css("height"), "4px", "Height on disconnected node." );
+
+       var div2 = jQuery( "<div style='display:none;'><input type='text' style='height:20px;'/><textarea style='height:20px;'/><div style='height:20px;'></div></div>").appendTo("body");
+
+       equals( div2.find("input").css("height"), "20px", "Height on hidden input." );
+       equals( div2.find("textarea").css("height"), "20px", "Height on hidden textarea." );
+       equals( div2.find("div").css("height"), "20px", "Height on hidden textarea." );
+
+       div2.remove();
+
        // handle negative numbers by ignoring #1599, #4216
        jQuery('#nothiddendiv').css({ 'width': 1, 'height': 1 });
 
@@ -19,6 +39,8 @@ test("css(String|Hash)", function() {
        equals( parseFloat(jQuery('#nothiddendiv').css('width')), width, 'Test negative width ignored')
        equals( parseFloat(jQuery('#nothiddendiv').css('height')), height, 'Test negative height ignored')
 
+       equals( jQuery('<div style="display: none;">').css('display'), 'none', 'Styles on disconnected nodes');
+
        jQuery('#floatTest').css({'float': 'right'});
        equals( jQuery('#floatTest').css('float'), 'right', 'Modified CSS float using "float": Assert float is right');
        jQuery('#floatTest').css({'font-size': '30px'});
@@ -111,9 +133,8 @@ test("css(String, Object)", function() {
 
        // using contents will get comments regular, text, and comment nodes
        var j = jQuery("#nonnodes").contents();
-       j.css("padding-left", "1px");
-       equals( j.css("padding-left"), "1px", "Check node,textnode,comment css works" );
-
+       j.css("overflow", "visible");
+       equals( j.css("overflow"), "visible", "Check node,textnode,comment css works" );
        // opera sometimes doesn't update 'display' correctly, see #2037
        jQuery("#t2037")[0].innerHTML = jQuery("#t2037")[0].innerHTML
        equals( jQuery("#t2037 .hidden").css("display"), "none", "Make sure browser thinks it is hidden" );
@@ -136,28 +157,28 @@ test("css(String, Object)", function() {
        ok( success, "Setting RGBA values does not throw Error" );
 });
 
-if(jQuery.browser.msie) {
-  test("css(String, Object) for MSIE", function() {
-    // for #1438, IE throws JS error when filter exists but doesn't have opacity in it
+if ( !jQuery.support.opacity ) {
+       test("css(String, Object) for MSIE", function() {
+               // for #1438, IE throws JS error when filter exists but doesn't have opacity in it
                jQuery('#foo').css("filter", "progid:DXImageTransform.Microsoft.Chroma(color='red');");
-       equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" );
-
-    var filterVal = "progid:DXImageTransform.Microsoft.Alpha(opacity=30) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
-    var filterVal2 = "progid:DXImageTransform.Microsoft.alpha(opacity=100) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
-    var filterVal3 = "progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
-    jQuery('#foo').css("filter", filterVal);
-    equals( jQuery('#foo').css("filter"), filterVal, "css('filter', val) works" );
-    jQuery('#foo').css("opacity", 1);
-    equals( jQuery('#foo').css("filter"), filterVal2, "Setting opacity in IE doesn't duplicate opacity filter" );
-    equals( jQuery('#foo').css("opacity"), 1, "Setting opacity in IE with other filters works" );
-    jQuery('#foo').css("filter", filterVal3).css("opacity", 1);
-    ok( jQuery('#foo').css("filter").indexOf(filterVal3) !== -1, "Setting opacity in IE doesn't clobber other filters" );
-  });
+               equals( jQuery('#foo').css('opacity'), '1', "Assert opacity is 1 when a different filter is set in IE, #1438" );
+
+               var filterVal = "progid:DXImageTransform.Microsoft.Alpha(opacity=30) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               var filterVal2 = "progid:DXImageTransform.Microsoft.alpha(opacity=100) progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               var filterVal3 = "progid:DXImageTransform.Microsoft.Blur(pixelradius=5)";
+               jQuery('#foo').css("filter", filterVal);
+               equals( jQuery('#foo').css("filter"), filterVal, "css('filter', val) works" );
+               jQuery('#foo').css("opacity", 1);
+               equals( jQuery('#foo').css("filter"), filterVal2, "Setting opacity in IE doesn't duplicate opacity filter" );
+               equals( jQuery('#foo').css("opacity"), 1, "Setting opacity in IE with other filters works" );
+               jQuery('#foo').css("filter", filterVal3).css("opacity", 1);
+               ok( jQuery('#foo').css("filter").indexOf(filterVal3) !== -1, "Setting opacity in IE doesn't clobber other filters" );
+       });
 }
 
 test("css(String, Function)", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -172,7 +193,7 @@ test("css(String, Function)", function() {
                index++;
                return size;
        });
-               
+       
        index = 0;
        
        jQuery("#cssFunctionTest div").each(function() {
@@ -187,7 +208,7 @@ test("css(String, Function)", function() {
 
 test("css(String, Function) with incoming value", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -202,7 +223,7 @@ test("css(String, Function) with incoming value", function() {
                index++;
                return size;
        });
-               
+       
        index = 0;
        
        jQuery("#cssFunctionTest div").css("font-size", function(i, computedSize) {
@@ -217,7 +238,7 @@ test("css(String, Function) with incoming value", function() {
 
 test("css(Object) where values are Functions", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -232,22 +253,22 @@ test("css(Object) where values are Functions", function() {
                index++;
                return size;
        }});
-               
+       
        index = 0;
-               
+       
        jQuery("#cssFunctionTest div").each(function() {
                var computedSize = jQuery(this).css("font-size")
                var expectedSize = sizes[index]
                equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
                index++;
        });
-               
+       
        jQuery("#cssFunctionTest").remove();
 });
 
 test("css(Object) where values are Functions with incoming values", function() {
        expect(3);
-               
+       
        var sizes = ["10px", "20px", "30px"];
        
        jQuery("<div id='cssFunctionTest'><div class='cssFunction'></div>" + 
@@ -262,16 +283,16 @@ test("css(Object) where values are Functions with incoming values", function() {
                index++;
                return size;
        }});
-               
+       
        index = 0;
-               
+       
        jQuery("#cssFunctionTest div").css({"font-size": function(i, computedSize) {
                var expectedSize = sizes[index]
                equals( computedSize, expectedSize, "Div #" + index + " should be " + expectedSize );
                index++;
                return computedSize;
        }});
-               
+       
        jQuery("#cssFunctionTest").remove();
 });
 
@@ -298,4 +319,4 @@ test(":visible selector works properly on children with a hidden parent (bug #45
        expect(1);
        jQuery('#table').css('display', 'none').html('<tr><td>cell</td><td>cell</td></tr>');
        equals(jQuery('#table td:visible').length, 0, "hidden cell children not perceived as visible");
-});
\ No newline at end of file
+});
index 2efa984..310cd6b 100644 (file)
@@ -38,7 +38,7 @@ test("jQuery.acceptData", function() {
 });
 
 test("jQuery.data", function() {
-       expect(12);
+       expect(15);
        var div = document.createElement("div");
 
        ok( jQuery.data(div, "test") === undefined, "Check for no data exists" );
@@ -71,10 +71,30 @@ test("jQuery.data", function() {
 
        ok( obj.prop, "Data is being stored on the object" );
        equals( jQuery.data( obj, "prop" ), true, "Make sure the right value is retrieved" );
+
+       jQuery.data( window, "BAD", true );
+       ok( !window[ jQuery.expando ], "Make sure there is no expando on the window object." );
+       ok( !window.BAD, "And make sure that the property wasn't set directly on the window." );
+       ok( jQuery.data( window, "BAD" ), "Make sure that the value was set." );
+});
+
+test("jQuery.hasData", function() {
+       expect(6);
+
+       function testData(obj) {
+               equals( jQuery.hasData(obj), false, "No data exists" );
+               jQuery.data( obj, "foo", "bar" );
+               equals( jQuery.hasData(obj), true, "Data exists" );
+               jQuery.removeData( obj, "foo" );
+               equals( jQuery.hasData(obj), false, "Data was removed" );
+       }
+
+       testData(document.createElement('div'));
+       testData({});
 });
 
 test(".data()", function() {
-       expect(4);
+       expect(5);
 
        var div = jQuery("#foo");
        strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" );
@@ -85,6 +105,9 @@ test(".data()", function() {
 
        var nodiv = jQuery("#unfound");
        equals( nodiv.data(), null, "data() on empty set returns null" );
+
+       var obj = { foo: "bar" };
+       equals( jQuery(obj).data(), obj, "Retrieve data object from a wrapped JS object (#7524)" );
 })
 
 test(".data(String) and .data(String, Object)", function() {
@@ -172,25 +195,29 @@ test(".data(String) and .data(String, Object)", function() {
        equals( $elem.data('emptyString','').data('emptyString'), '', "Empty strings are preserved");
        equals( $elem.data('false',false).data('false'), false, "false's are preserved");
        equals( $elem.data('exists'), true, "Existing data is returned" );
-       
+
        // Clean up
        $elem.removeData();
        ok( jQuery.isEmptyObject( $elem[0] ), "removeData clears the object" );
 });
 
 test("data-* attributes", function() {
-       expect(27);
+       expect(37);
        var div = jQuery("<div>"),
-               child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\"></div>");
-               
+               child = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>"),
+               dummy = jQuery("<div data-myobj='old data' data-ignored=\"DOM\" data-other='test'></div>");
+
        equals( div.data("attr"), undefined, "Check for non-existing data-attr attribute" );
 
        div.attr("data-attr", "exists");
        equals( div.data("attr"), "exists", "Check for existing data-attr attribute" );
-               
+
+       div.attr("data-attr", "exists2");
+       equals( div.data("attr"), "exists", "Check that updates to data- don't update .data()" );
+
        div.data("attr", "internal").attr("data-attr", "external");
        equals( div.data("attr"), "internal", "Check for .data('attr') precedence (internal > external data-* attribute)" );
-       
+
        child.appendTo('#main');
        equals( child.data("myobj"), "old data", "Value accessed from data-* attribute");
 
@@ -200,6 +227,29 @@ test("data-* attributes", function() {
        child.data("ignored", "cache");
        equals( child.data("ignored"), "cache", "Cached data used before DOM data-* fallback");
 
+       var obj = child.data(), obj2 = dummy.data(), check = [ "myobj", "ignored", "other" ], num = 0, num2 = 0;
+
+       for ( var i = 0, l = check.length; i < l; i++ ) {
+               ok( obj[ check[i] ], "Make sure data- property exists when calling data-." );
+               ok( obj2[ check[i] ], "Make sure data- property exists when calling data-." );
+       }
+
+       for ( var prop in obj ) {
+               num++;
+       }
+
+       equals( num, check.length, "Make sure that the right number of properties came through." );
+
+       for ( var prop in obj2 ) {
+               num2++;
+       }
+
+       equals( num2, check.length, "Make sure that the right number of properties came through." );
+
+       child.attr("data-other", "newvalue");
+
+       equals( child.data("other"), "test", "Make sure value was pulled in properly from a .data()." );
+
        child
                .attr("data-true", "true")
                .attr("data-false", "false")
@@ -214,7 +264,7 @@ test("data-* attributes", function() {
                .attr("data-space", " ")
                .attr("data-null", "null")
                .attr("data-string", "test");
-       
+
        strictEqual( child.data('true'), true, "Primitive true read from attribute");
        strictEqual( child.data('false'), false, "Primitive false read from attribute");
        strictEqual( child.data('five'), 5, "Primitive number read from attribute");
@@ -230,7 +280,7 @@ test("data-* attributes", function() {
        strictEqual( child.data('string'), "test", "Typical string read from attribute");
 
        child.remove();
-       
+
        // tests from metadata plugin
        function testData(index, elem) {
                switch (index) {
@@ -254,10 +304,10 @@ test("data-* attributes", function() {
                        ok(false, ["Assertion failed on index ", index, ", with data ", data].join(''));
                }
        }
-       
+
        var metadata = '<ol><li class="test test2" data-foo="bar" data-bar="baz" data-arr="[1,2]">Some stuff</li><li class="test test2" data-test="bar" data-bar="baz">Some stuff</li><li class="test test2" data-zoooo="bar" data-bar=\'{"test":"baz"}\'>Some stuff</li><li class="test test2" data-number=true data-stuff="[2,8]">Some stuff</li></ol>',
                elem = jQuery(metadata).appendTo('#main');
-       
+
        elem.find("li").each(testData);
        elem.remove();
 });
@@ -270,27 +320,36 @@ test(".data(Object)", function() {
        div.data({ "test": "in", "test2": "in2" });
        equals( div.data("test"), "in", "Verify setting an object in data" );
        equals( div.data("test2"), "in2", "Verify setting an object in data" );
-       
+
        var obj = {test:"unset"},
                jqobj = jQuery(obj);
        jqobj.data({ "test": "in", "test2": "in2" });
        equals( obj.test, "in", "Verify setting an object on an object extends the object" );
-       equals( obj.test2, "in2", "Verify setting an object on an object extends the object" ); 
+       equals( obj.test2, "in2", "Verify setting an object on an object extends the object" );
 });
 
 test("jQuery.removeData", function() {
-       expect(4);
+       expect(7);
        var div = jQuery("#foo")[0];
        jQuery.data(div, "test", "testing");
        jQuery.removeData(div, "test");
        equals( jQuery.data(div, "test"), undefined, "Check removal of data" );
-       
+
+       jQuery.data(div, "test2", "testing");
+       jQuery.removeData( div );
+       ok( !jQuery.data(div, "test2"), "Make sure that the data property no longer exists." );
+       ok( !div[ jQuery.expando ], "Make sure the expando no longer exists, as well." );
+
        var obj = {};
        jQuery.data(obj, "test", "testing");
        equals( obj.test, "testing", "verify data on plain object");
        jQuery.removeData(obj, "test");
        equals( jQuery.data(obj, "test"), undefined, "Check removal of data on plain object" );
-       equals( obj.test, undefined, "Check removal of data directly from plain object" );      
+       equals( obj.test, undefined, "Check removal of data directly from plain object" );
+
+       jQuery.data( window, "BAD", true );
+       jQuery.removeData( window, "BAD" );
+       ok( !jQuery.data( window, "BAD" ), "Make sure that the value was not still set." );
 });
 
 test(".removeData()", function() {
index 92cf17b..8255bf3 100644 (file)
@@ -103,7 +103,7 @@ test("height() with function args", function() {
 });
 
 test("innerWidth()", function() {
-       expect(3);
+       expect(4);
 
        var $div = jQuery("#nothiddendiv");
        // set styles
@@ -121,10 +121,15 @@ test("innerWidth()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.innerWidth(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("innerHeight()", function() {
-       expect(3);
+       expect(4);
        
        var $div = jQuery("#nothiddendiv");
        // set styles
@@ -142,10 +147,15 @@ test("innerHeight()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.innerHeight(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("outerWidth()", function() {
-       expect(6);
+       expect(7);
        
        var $div = jQuery("#nothiddendiv");
        $div.css("width", 30);
@@ -164,10 +174,15 @@ test("outerWidth()", function() {
        
        // reset styles
        $div.css({ position: "", display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.outerWidth(), 0, "Make sure that disconnected nodes are handled." );
 });
 
 test("outerHeight()", function() {
-       expect(6);
+       expect(7);
        
        var $div = jQuery("#nothiddendiv");
        $div.css("height", 30);
@@ -185,4 +200,9 @@ test("outerHeight()", function() {
        
        // reset styles
        $div.css({ display: "", border: "", padding: "", width: "", height: "" });
+
+       var div = jQuery( "<div>" );
+
+       // Temporarily require 0 for backwards compat - should be auto
+       equals( div.outerHeight(), 0, "Make sure that disconnected nodes are handled." );
 });
index 3c4015a..9690796 100644 (file)
@@ -6,7 +6,32 @@ test("sanity check", function() {
 });
 
 test("show()", function() {
-       expect(23);
+       expect(28);
+
+       var hiddendiv = jQuery("div.hidden");
+
+       hiddendiv.hide().show();
+
+       equals( hiddendiv.css("display"), "block", "Make sure a pre-hidden div is visible." );
+
+       var div = jQuery("<div>").hide().appendTo("body").show();
+
+       equal( div.css("display"), "block", "Make sure pre-hidden divs show" );
+
+       QUnit.reset();
+
+       hiddendiv = jQuery("div.hidden");
+
+       equal(jQuery.css( hiddendiv[0], "display"), "none", "hiddendiv is display: none");
+
+       hiddendiv.css("display", "block");
+       equal(jQuery.css( hiddendiv[0], "display"), "block", "hiddendiv is display: block");
+
+       hiddendiv.show();
+       equal(jQuery.css( hiddendiv[0], "display"), "block", "hiddendiv is display: block");
+
+       hiddendiv.css("display","");
+
        var pass = true, div = jQuery("#main div");
        div.show().each(function(){
                if ( this.style.display == "none" ) pass = false;
@@ -105,6 +130,45 @@ test("show(Number) - other displays", function() {
        });
 });
 
+
+
+//  Supports #7397
+test("Persist correct display value", function() {
+  expect(3);
+       QUnit.reset();
+       stop();
+
+       // #show-tests * is set display: none in CSS
+       jQuery("#main").append('<div id="show-tests"><span style="position:absolute;">foo</span></div>');
+  
+       var $span = jQuery("#show-tests span"),  
+         displayNone = $span.css("display"),
+         display = '', num = 0;
+               
+  $span.show();
+  
+  display = $span.css("display");
+  
+  $span.hide();
+
+  $span.fadeIn(100, function() {
+
+    equals($span.css("display"), display, "Expecting display: " + display);
+
+    $span.fadeOut(100, function () {
+  
+      equals($span.css("display"), displayNone, "Expecting display: " + displayNone);
+      
+      $span.fadeIn(100, function() {
+      
+        equals($span.css("display"), display, "Expecting display: " + display);
+      
+        start();
+      });
+    });
+  });
+});
+
 test("animate(Hash, Object, Function)", function() {
        expect(1);
        stop();
@@ -127,27 +191,56 @@ test("animate negative height", function() {
 
 test("animate block as inline width/height", function() {
        expect(3);
-       stop();
-       jQuery("#foo").css({ display: "inline", width: '', height: '' }).animate({ width: 42, height: 42 }, 100, function() {
-               equals( jQuery(this).css("display"), jQuery.support.inlineBlockNeedsLayout ? "inline" : "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
-               equals( this.offsetWidth, 42, "width was animated" );
-               equals( this.offsetHeight, 42, "height was animated" );
-               start();
-       });
+
+       var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
+               expected = span.css("display");
+       
+       span.remove();
+
+       if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
+               stop();
+
+               jQuery("#foo").css({ display: "inline", width: '', height: '' }).animate({ width: 42, height: 42 }, 100, function() {
+                       equals( jQuery(this).css("display"), jQuery.support.inlineBlockNeedsLayout ? "inline" : "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
+                       equals( this.offsetWidth, 42, "width was animated" );
+                       equals( this.offsetHeight, 42, "height was animated" );
+                       start();
+               });
+
+       // Browser doesn't support inline-block
+       } else {
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+       }
 });
 
 test("animate native inline width/height", function() {
        expect(3);
-       stop();
-       jQuery("#foo").css({ display: "", width: '', height: '' })
-               .append('<span>text</span>')
-               .children('span')
-                       .animate({ width: 42, height: 42 }, 100, function() {
-                               equals( jQuery(this).css("display"), "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
-                               equals( this.offsetWidth, 42, "width was animated" );
-                               equals( this.offsetHeight, 42, "height was animated" );
-                               start();
-                       });
+
+       var span = jQuery("<span>").css("display", "inline-block").appendTo("body"),
+               expected = span.css("display");
+       
+       span.remove();
+
+       if ( jQuery.support.inlineBlockNeedsLayout || expected === "inline-block" ) {
+               stop();
+               jQuery("#foo").css({ display: "", width: '', height: '' })
+                       .append('<span>text</span>')
+                       .children('span')
+                               .animate({ width: 42, height: 42 }, 100, function() {
+                                       equals( jQuery(this).css("display"), "inline-block", "inline-block was set on non-floated inline element when animating width/height" );
+                                       equals( this.offsetWidth, 42, "width was animated" );
+                                       equals( this.offsetHeight, 42, "height was animated" );
+                                       start();
+                               });
+
+       // Browser doesn't support inline-block
+       } else {
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+               ok( true, "Browser doesn't support inline-block" );
+       }
 });
 
 test("animate block width/height", function() {
@@ -700,6 +793,13 @@ test("Chain slideToggle out", function() {
        jQuery('#slidetoggleout div').saveState(jQuery.support.shrinkWrapBlocks).slideToggle('fast').slideToggle('fast',jQuery.checkState);
 });
 
+test("Chain fadeToggle in", function() {
+       jQuery('#fadetogglein div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState);
+});
+test("Chain fadeToggle out", function() {
+       jQuery('#fadetoggleout div').saveState().fadeToggle('fast').fadeToggle('fast',jQuery.checkState);
+});
+
 test("Chain fadeTo 0.5 1.0 with easing and callback)", function() {
        jQuery('#fadeto div').saveState().fadeTo('fast',0.5).fadeTo('fast',1.0,'linear',jQuery.checkState);
 });
@@ -770,3 +870,33 @@ test("animate with per-property easing", function(){
        });
 
 });
+
+test("hide hidden elements (bug #7141)", function() {
+       expect(3);
+       QUnit.reset();
+
+       var div = jQuery("<div style='display:none'></div>").appendTo("#main");
+       equals( div.css("display"), "none", "Element is hidden by default" );
+       div.hide();
+       ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+       div.show();
+       equals( div.css("display"), "block", "Show a double-hidden element" );
+
+       div.remove();
+});
+
+test("hide hidden elements, with animation (bug #7141)", function() {
+       expect(3);
+       QUnit.reset();
+       stop();
+       
+       var div = jQuery("<div style='display:none'></div>").appendTo("#main");
+       equals( div.css("display"), "none", "Element is hidden by default" );
+       div.hide(1, function () {
+               ok( !div.data("olddisplay"), "olddisplay is undefined after hiding an already-hidden element" );
+               div.show(1, function () {
+                       equals( div.css("display"), "block", "Show a double-hidden element" );
+                       start();
+               });
+       });
+});
index b5e24c8..a647e5f 100644 (file)
@@ -1,5 +1,25 @@
 module("event");
 
+test("null or undefined handler", function() {
+       expect(2);
+  // Supports Fixes bug #7229
+  try {
+  
+    jQuery("#firstp").click(null);
+  
+    ok(true, "Passing a null handler will not throw an exception");
+
+  } catch (e) {}  
+
+  try {
+  
+    jQuery("#firstp").click(undefined);
+  
+    ok(true, "Passing an undefined handler will not throw an exception");
+
+  } catch (e) {}  
+});
+
 test("bind(), with data", function() {
        expect(3);
        var handler = function(event) {
@@ -245,6 +265,36 @@ test("live/die(Object), delegate/undelegate(String, Object)", function() {
        equals( mouseoverCounter, 4, "die" );
 });
 
+test("live/delegate immediate propagation", function() {
+       expect(2);
+       
+       var $p = jQuery("#firstp"), $a = $p.find("a:first"), lastClick;
+       
+       lastClick = "";
+       $a.live( "click", function(e) { 
+               lastClick = "click1"; 
+               e.stopImmediatePropagation();
+       });
+       $a.live( "click", function(e) {
+               lastClick = "click2";
+       });
+       $a.trigger( "click" );
+       equals( lastClick, "click1", "live stopImmediatePropagation" );
+       $a.die( "click" );
+       
+       lastClick = "";
+       $p.delegate( "a", "click", function(e) { 
+               lastClick = "click1"; 
+               e.stopImmediatePropagation();
+       });
+       $p.delegate( "a", "click", function(e) {
+               lastClick = "click2";
+       });
+       $a.trigger( "click" );
+       equals( lastClick, "click1", "delegate stopImmediatePropagation" );
+       $p.undelegate( "click" );
+});
+
 test("bind(), iframes", function() {
        // events don't work with iframes, see #939 - this test fails in IE because of contentDocument
        var doc = jQuery("#loadediframe").contents();
@@ -443,7 +493,7 @@ test("bind(name, false), unbind(name, false)", function() {
 });
 
 test("bind()/trigger()/unbind() on plain object", function() {
-       expect( 5 );
+       expect( 8 );
 
        var obj = {};
 
@@ -453,26 +503,36 @@ test("bind()/trigger()/unbind() on plain object", function() {
        // Make sure it doesn't complain when no events are found
        jQuery(obj).unbind("test");
 
-       jQuery(obj).bind("test", function(){
-               ok( true, "Custom event run." );
+       jQuery(obj).bind({
+               test: function() {
+                       ok( true, "Custom event run." );
+               },
+               submit: function() {
+                       ok( true, "Custom submit event run." );
+               }
        });
 
-       var events = jQuery(obj).data("events");
+       var events = jQuery(obj).data("__events__");
        ok( events, "Object has events bound." );
+       equals( obj.events, undefined, "Events object on plain objects is not events" );
        equals( typeof events, "function", "'events' expando is a function on plain objects." );
        equals( obj.test, undefined, "Make sure that test event is not on the plain object." );
        equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );
 
        // Should trigger 1
        jQuery(obj).trigger("test");
+       jQuery(obj).trigger("submit");
 
        jQuery(obj).unbind("test");
+       jQuery(obj).unbind("submit");
 
        // Should trigger 0
        jQuery(obj).trigger("test");
 
        // Make sure it doesn't complain when no events are found
        jQuery(obj).unbind("test");
+       
+       equals( obj.__events__, undefined, "Make sure events object is removed" );
 });
 
 test("unbind(type)", function() {
@@ -1235,6 +1295,8 @@ test("live with namespaces", function(){
 });
 
 test("live with change", function(){
+       expect(8);
+
        var selectChange = 0, checkboxChange = 0;
        
        var select = jQuery("select[name='S1']")
@@ -1266,28 +1328,13 @@ test("live with change", function(){
        checkbox.trigger("change");
        equals( checkboxChange, 1, "Change on checkbox." );
        
-       // test before activate on radio
-       
-       // test blur/focus on textarea
-       var textarea = jQuery("#area1"), textareaChange = 0, oldVal = textarea.val();
-       textarea.live("change", function() {
-               textareaChange++;
-       });
-
-       textarea.val(oldVal + "foo");
-       textarea.trigger("change");
-       equals( textareaChange, 1, "Change on textarea." );
-
-       textarea.val(oldVal);
-       textarea.die("change");
-       
        // test blur/focus on text
        var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
        text.live("change", function() {
                textChange++;
        });
 
-       text.val(oldVal+"foo");
+       text.val(oldTextVal+"foo");
        text.trigger("change");
        equals( textChange, 1, "Change on text input." );
 
@@ -1704,6 +1751,8 @@ test("delegate with multiple events", function(){
 });
 
 test("delegate with change", function(){
+       expect(8);
+
        var selectChange = 0, checkboxChange = 0;
        
        var select = jQuery("select[name='S1']");
@@ -1735,28 +1784,13 @@ test("delegate with change", function(){
        checkbox.trigger("change");
        equals( checkboxChange, 1, "Change on checkbox." );
        
-       // test before activate on radio
-       
-       // test blur/focus on textarea
-       var textarea = jQuery("#area1"), textareaChange = 0, oldVal = textarea.val();
-       jQuery("#body").delegate("#area1", "change", function() {
-               textareaChange++;
-       });
-
-       textarea.val(oldVal + "foo");
-       textarea.trigger("change");
-       equals( textareaChange, 1, "Change on textarea." );
-
-       textarea.val(oldVal);
-       jQuery("#body").undelegate("#area1", "change");
-       
        // test blur/focus on text
        var text = jQuery("#name"), textChange = 0, oldTextVal = text.val();
        jQuery("#body").delegate("#name", "change", function() {
                textChange++;
        });
 
-       text.val(oldVal+"foo");
+       text.val(oldTextVal+"foo");
        text.trigger("change");
        equals( textChange, 1, "Change on text input." );
 
@@ -1829,6 +1863,38 @@ test("Non DOM element events", function() {
        jQuery(o).trigger('nonelementobj');
 });
 
+test("window resize", function() {
+       expect(2);
+
+       jQuery(window).unbind();
+
+       jQuery(window).bind("resize", function(){
+               ok( true, "Resize event fired." );
+       }).resize().unbind("resize");
+
+       ok( !jQuery(window).data("__events__"), "Make sure all the events are gone." );
+});
+
+test("focusin bubbles", function() {
+       //create an input and focusin on it
+       var input = jQuery("<input/>"), order = 0;
+
+       input.prependTo("body");
+
+       jQuery("body").bind("focusin.focusinBubblesTest",function(){
+               equals(1,order++,"focusin on the body second")
+       });
+
+       input.bind("focusin.focusinBubblesTest",function(){
+               equals(0,order++,"focusin on the element first")
+       });
+
+       input[0].focus();
+       input.remove();
+
+       jQuery("body").unbind("focusin.focusinBubblesTest");
+});
+
 /*
 test("jQuery(function($) {})", function() {
        stop();
index d4c4348..da16354 100644 (file)
@@ -1,5 +1,8 @@
 module("manipulation");
 
+// Ensure that an extended Array prototype doesn't break jQuery
+Array.prototype.arrayProtoFn = function(arg) { throw("arrayProtoFn should not be called"); };
+
 var bareObj = function(value) { return value; };
 var functionReturningObj = function(value) { return (function() { return value; }); };
 
@@ -37,21 +40,21 @@ test("text(Function)", function() {
 
 test("text(Function) with incoming value", function() {
        expect(2);
-       
+
        var old = "This link has class=\"blog\": Simon Willison's Weblog";
-       
+
        jQuery('#sap').text(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return "foobar";
        });
-       
+
        equals( jQuery("#sap").text(), "foobar", 'Check for merged text of more then one element.' );
-       
+
        QUnit.reset();
 });
 
 var testWrap = function(val) {
-       expect(18);
+       expect(19);
        var defaultText = 'Try them out:'
        var result = jQuery('#first').wrap(val( '<div class="red"><span></span></div>' )).text();
        equals( defaultText, result, 'Check for wrapping of on-the-fly html' );
@@ -80,10 +83,20 @@ var testWrap = function(val) {
        equals( jQuery("#nonnodes > i").text(), j.text(), "Check node,textnode,comment wraps doesn't hurt text" );
 
        // Try wrapping a disconnected node
+       var cacheLength = 0;
+       for (var i in jQuery.cache) {
+               cacheLength++;
+       }
+
        j = jQuery("<label/>").wrap(val( "<li/>" ));
        equals( j[0].nodeName.toUpperCase(), "LABEL", "Element is a label" );
        equals( j[0].parentNode.nodeName.toUpperCase(), "LI", "Element has been wrapped" );
 
+       for (i in jQuery.cache) {
+               cacheLength--;
+       }
+       equals(cacheLength, 0, "No memory leak in jQuery.cache (bug #7165)");
+
        // Wrap an element containing a text node
        j = jQuery("<span/>").wrap("<div>test</div>");
        equals( j[0].previousSibling.nodeType, 3, "Make sure the previous node is a text element" );
@@ -240,7 +253,7 @@ var testAppend = function(valueObj) {
        ok( jQuery("#sap").append(valueObj( [] )), "Check for appending an empty array." );
        ok( jQuery("#sap").append(valueObj( "" )), "Check for appending an empty string." );
        ok( jQuery("#sap").append(valueObj( document.getElementsByTagName("foo") )), "Check for appending an empty nodelist." );
-       
+
        QUnit.reset();
        jQuery("form").append(valueObj('<input name="radiotest" type="radio" checked="checked" />'));
        jQuery("form input[name=radiotest]").each(function(){
@@ -322,18 +335,18 @@ test("append(Function)", function() {
 
 test("append(Function) with incoming value", function() {
        expect(12);
-       
+
        var defaultText = 'Try them out:', old = jQuery("#first").html();
-       
+
        var result = jQuery('#first').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return '<b>buga</b>';
        });
        equals( result.text(), defaultText + 'buga', 'Check if text appending works' );
-       
+
        var select = jQuery('#select3');
        old = select.html();
-       
+
        equals( select.append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return '<option value="appendTest">Append Test</option>';
@@ -342,7 +355,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        var expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return document.getElementById('first');
@@ -352,7 +365,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        expected = "This link has class=\"blog\": Simon Willison's WeblogTry them out:Yahoo";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return [document.getElementById('first'), document.getElementById('yahoo')];
@@ -362,7 +375,7 @@ test("append(Function) with incoming value", function() {
        QUnit.reset();
        expected = "This link has class=\"blog\": Simon Willison's WeblogYahooTry them out:";
        old = jQuery("#sap").html();
-       
+
        jQuery('#sap').append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return jQuery("#yahoo, #first");
@@ -371,16 +384,58 @@ test("append(Function) with incoming value", function() {
 
        QUnit.reset();
        old = jQuery("#sap").html();
-       
+
        jQuery("#sap").append(function(i, val){
                equals( val, old, "Make sure the incoming value is correct." );
                return 5;
        });
-       ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" );        
-       
+       ok( jQuery("#sap")[0].innerHTML.match( /5$/ ), "Check for appending a number" );
+
        QUnit.reset();
 });
 
+test("append the same fragment with events (Bug #6997, 5566)", function () {
+       expect(4 + (document.fireEvent ? 1 : 0));
+       stop(1000);
+
+       var element;
+
+       // This patch modified the way that cloning occurs in IE; we need to make sure that
+       // native event handlers on the original object don't get disturbed when they are
+       // modified on the clone
+       if (!jQuery.support.noCloneEvent && document.fireEvent) {
+               element = jQuery("div:first").click(function () {
+                       ok(true, "Event exists on original after being unbound on clone");
+                       jQuery(this).unbind('click');
+               });
+               element.clone(true).unbind('click')[0].fireEvent('onclick');
+               element[0].fireEvent('onclick');
+       }
+
+       element = jQuery("<a class='test6997'></a>").click(function () {
+               ok(true, "Append second element events work");
+       });
+
+       jQuery("#listWithTabIndex li").append(element)
+               .find('a.test6997').eq(1).click();
+
+       element = jQuery("<li class='test6997'></li>").click(function () {
+               ok(true, "Before second element events work");
+               start();
+       });
+
+       jQuery("#listWithTabIndex li").before(element);
+       jQuery("#listWithTabIndex li.test6997").eq(1).click();
+
+       element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
+
+       equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
+
+       element = jQuery("<input type='checkbox'>").attr('checked', 'checked');
+
+       equals( element.clone().is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
+});
+
 test("appendTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
        expect(16);
 
@@ -489,16 +544,16 @@ test("prepend(Function)", function() {
 
 test("prepend(Function) with incoming value", function() {
        expect(10);
-       
+
        var defaultText = 'Try them out:', old = jQuery('#first').html();
        var result = jQuery('#first').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return '<b>buga</b>';
        });
        equals( result.text(), 'buga' + defaultText, 'Check if text prepending works' );
-       
+
        old = jQuery("#select3").html();
-       
+
        equals( jQuery('#select3').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return '<option value="prependTest">Prepend Test</option>';
@@ -507,35 +562,35 @@ test("prepend(Function) with incoming value", function() {
        QUnit.reset();
        var expected = "Try them out:This link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return document.getElementById('first');
        });
-       
+
        equals( jQuery('#sap').text(), expected, "Check for prepending of element" );
 
        QUnit.reset();
        expected = "Try them out:YahooThis link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return [document.getElementById('first'), document.getElementById('yahoo')];
        });
-       
+
        equals( jQuery('#sap').text(), expected, "Check for prepending of array of elements" );
 
        QUnit.reset();
        expected = "YahooTry them out:This link has class=\"blog\": Simon Willison's Weblog";
        old = jQuery('#sap').html();
-       
+
        jQuery('#sap').prepend(function(i, val) {
                equals( val, old, "Make sure the incoming value is correct." );
                return jQuery("#yahoo, #first");
        });
-       
-       equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );     
+
+       equals( jQuery('#sap').text(), expected, "Check for prepending of jQuery object" );
 });
 
 test("prependTo(String|Element|Array&lt;Element&gt;|jQuery)", function() {
@@ -814,7 +869,7 @@ test("replaceAll(String|Element|Array&lt;Element&gt;|jQuery)", function() {
 });
 
 test("clone()", function() {
-       expect(31);
+       expect(37);
        equals( 'This is a normal link: Yahoo', jQuery('#en').text(), 'Assert text for #en' );
        var clone = jQuery('#yahoo').clone();
        equals( 'Try them out:Yahoo', jQuery('#first').append(clone).text(), 'Check for clone' );
@@ -828,7 +883,7 @@ test("clone()", function() {
        ];
        for (var i = 0; i < cloneTags.length; i++) {
                var j = jQuery(cloneTags[i]);
-               equals( j[0].tagName, j.clone()[0].tagName, 'Clone a &lt;' + cloneTags[i].substring(1));
+               equals( j[0].tagName, j.clone()[0].tagName, 'Clone a ' + cloneTags[i]);
        }
 
        // using contents will get comments regular, text, and comment nodes
@@ -854,16 +909,30 @@ test("clone()", function() {
        equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
        div.find("table:last").trigger("click");
 
-       div = jQuery("<div/>").html('<object height="355" width="425">  <param name="movie" value="http://www.youtube.com/v/JikaHBDoV3k&amp;hl=en">  <param name="wmode" value="transparent"> </object>');
+       // this is technically an invalid object, but because of the special
+       // classid instantiation it is the only kind that IE has trouble with,
+       // so let's test with it too.
+       div = jQuery("<div/>").html('<object height="355" width="425" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">  <param name="movie" value="http://www.youtube.com/v/3KANI2dpXLw&amp;hl=en">  <param name="wmode" value="transparent"> </object>');
 
-       div = div.clone(true);
-       equals( div.length, 1, "One element cloned" );
-       equals( div[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
+       clone = div.clone(true);
+       equals( clone.length, 1, "One element cloned" );
+       equals( clone.html(), div.html(), "Element contents cloned" );
+       equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
 
-       div = jQuery("<div/>").data({ a: true, b: true });
-       div = div.clone(true);
-       equals( div.data("a"), true, "Data cloned." );
-       equals( div.data("b"), true, "Data cloned." );
+       // and here's a valid one.
+       div = jQuery("<div/>").html('<object height="355" width="425" type="application/x-shockwave-flash" data="http://www.youtube.com/v/3KANI2dpXLw&amp;hl=en">  <param name="movie" value="http://www.youtube.com/v/3KANI2dpXLw&amp;hl=en">  <param name="wmode" value="transparent"> </object>');
+
+       clone = div.clone(true);
+       equals( clone.length, 1, "One element cloned" );
+       equals( clone.html(), div.html(), "Element contents cloned" );
+       equals( clone[0].nodeName.toUpperCase(), "DIV", "DIV element cloned" );
+
+       div = jQuery("<div/>").data({ a: true });
+       var div2 = div.clone(true);
+       equals( div2.data("a"), true, "Data cloned." );
+       div2.data("a", false);
+       equals( div2.data("a"), false, "Ensure cloned element data object was correctly modified" );
+       equals( div.data("a"), true, "Ensure cloned element data object is copied, not referenced" );
 
        var form = document.createElement("form");
        form.action = "/test/";
@@ -872,6 +941,8 @@ test("clone()", function() {
        form.appendChild( div );
 
        equals( jQuery(form).clone().children().length, 1, "Make sure we just get the form back." );
+
+       equal( jQuery("body").clone().children()[0].id, "qunit-header", "Make sure cloning body works" );
 });
 
 if (!isLocal) {
@@ -981,14 +1052,14 @@ test("html(Function)", function() {
 
 test("html(Function) with incoming value", function() {
        expect(20);
-       
+
        var div = jQuery("#main > div"), old = div.map(function(){ return jQuery(this).html() });
-       
+
        div.html(function(i, val) {
                equals( val, old[i], "Make sure the incoming value is correct." );
                return "<b>test</b>";
        });
-       
+
        var pass = true;
        div.each(function(){
                if ( this.childNodes.length !== 1 ) {
@@ -1001,7 +1072,7 @@ test("html(Function) with incoming value", function() {
        // using contents will get comments regular, text, and comment nodes
        var j = jQuery("#nonnodes").contents();
        old = j.map(function(){ return jQuery(this).html(); });
-       
+
        j.html(function(i, val) {
                equals( val, old[i], "Make sure the incoming value is correct." );
                return "<b>bold</b>";
@@ -1011,17 +1082,17 @@ test("html(Function) with incoming value", function() {
        if ( j.length === 2 ) {
                equals( null, null, "Make sure the incoming value is correct." );
        }
-       
+
        j.find('b').removeData();
        equals( j.html().replace(/ xmlns="[^"]+"/g, "").toLowerCase(), "<b>bold</b>", "Check node,textnode,comment with html()" );
-       
+
        var $div = jQuery('<div />');
-       
+
        equals( $div.html(function(i, val) {
                equals( val, "", "Make sure the incoming value is correct." );
                return 5;
        }).html(), '5', 'Setting a number as html' );
-       
+
        equals( $div.html(function(i, val) {
                equals( val, "5", "Make sure the incoming value is correct." );
                return 0;
@@ -1032,16 +1103,16 @@ test("html(Function) with incoming value", function() {
                equals( val, "", "Make sure the incoming value is correct." );
                return insert;
        }).html().replace(/>/g, "&gt;"), insert, "Verify escaped insertion." );
-       
+
        equals( $div2.html(function(i, val) {
                equals( val.replace(/>/g, "&gt;"), insert, "Make sure the incoming value is correct." );
                return "x" + insert;
        }).html().replace(/>/g, "&gt;"), "x" + insert, "Verify escaped insertion." );
-       
+
        equals( $div2.html(function(i, val) {
                equals( val.replace(/>/g, "&gt;"), "x" + insert, "Make sure the incoming value is correct." );
                return " " + insert;
-       }).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );   
+       }).html().replace(/>/g, "&gt;"), " " + insert, "Verify escaped insertion." );
 });
 
 var testRemove = function(method) {
@@ -1075,9 +1146,9 @@ var testRemove = function(method) {
        var count = 0;
        var first = jQuery("#ap").children(":first");
        var cleanUp = first.click(function() { count++ })[method]().appendTo("body").click();
-       
+
        equals( method == "remove" ? 0 : 1, count );
-       
+
        cleanUp.detach();
 };
 
@@ -1102,58 +1173,58 @@ test("empty()", function() {
 
 test("jQuery.cleanData", function() {
        expect(14);
-       
+
        var type, pos, div, child;
-       
+
        type = "remove";
-       
+
        // Should trigger 4 remove event
        div = getDiv().remove();
-       
+
        // Should both do nothing
        pos = "Outer";
        div.trigger("click");
-       
+
        pos = "Inner";
        div.children().trigger("click");
-       
+
        type = "empty";
        div = getDiv();
        child = div.children();
-       
+
        // Should trigger 2 remove event
        div.empty();
-       
+
        // Should trigger 1
        pos = "Outer";
        div.trigger("click");
-       
+
        // Should do nothing
        pos = "Inner";
        child.trigger("click");
 
        // Should trigger 2
        div.remove();
-       
+
        type = "html";
-       
+
        div = getDiv();
        child = div.children();
-       
+
        // Should trigger 2 remove event
        div.html("<div></div>");
-       
+
        // Should trigger 1
        pos = "Outer";
        div.trigger("click");
-       
+
        // Should do nothing
        pos = "Inner";
        child.trigger("click");
 
        // Should trigger 2
        div.remove();
-       
+
        function getDiv() {
                var div = jQuery("<div class='outer'><div class='inner'></div></div>").click(function(){
                        ok( true, type + " " + pos + " Click event fired." );
@@ -1164,15 +1235,15 @@ test("jQuery.cleanData", function() {
                }).focus(function(){
                        ok( false, type + " " + pos + " Focus event fired." );
                }).end().appendTo("body");
-               
+
                div[0].detachEvent = div[0].removeEventListener = function(t){
                        ok( true, type + " Outer " + t + " event unbound" );
                };
-               
+
                div[0].firstChild.detachEvent = div[0].firstChild.removeEventListener = function(t){
                        ok( true, type + " Inner " + t + " event unbound" );
                };
-               
+
                return div;
        }
 });
index af59fa6..6ec20bc 100644 (file)
@@ -1,7 +1,7 @@
 module("selector");
 
 test("element", function() {
-       expect(19);
+       expect(21);
        QUnit.reset();
 
        ok( jQuery("*").size() >= 30, "Select all" );
@@ -27,17 +27,21 @@ test("element", function() {
        ok( jQuery("#lengthtest input").length, '&lt;input name="length"&gt; cannot be found under IE, see #945' );
 
        // Check for unique-ness and sort order
-       same( jQuery("*, *").get(), jQuery("*").get(), "Check for duplicates: *, *" );
        same( jQuery("p, div p").get(), jQuery("p").get(), "Check for duplicates: p, div p" );
 
        t( "Checking sort order", "h2, h1", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
        t( "Checking sort order", "h2:first, h1:first", ["qunit-header", "qunit-banner"] );
        t( "Checking sort order", "p, p a", ["firstp", "simon1", "ap", "google", "groups", "anchor1", "mark", "sndp", "en", "yahoo", "sap", "anchor2", "simon", "first"] );
+
+       // Test Conflict ID
+       same( jQuery("#lengthtest").find("#idTest").get(), q("idTest"), "Finding element with id of ID." );
+       same( jQuery("#lengthtest").find("[name='id']").get(), q("idTest"), "Finding element with id of ID." );
+       same( jQuery("#lengthtest").find("input[id='idTest']").get(), q("idTest"), "Finding elements with a context." );
 });
 
 if ( location.protocol != "file:" ) {
        test("XML Document Selectors", function() {
-               expect(7);
+               expect(8);
                stop();
                jQuery.get("data/with_fries.xml", function(xml) {
                        equals( jQuery("foo_bar", xml).length, 1, "Element Selector with underscore" );
@@ -47,6 +51,7 @@ if ( location.protocol != "file:" ) {
                        equals( jQuery("[name=prop2]", xml).length, 1, "Attribute selector with name" );
                        equals( jQuery("#seite1", xml).length, 1, "Attribute selector with ID" );
                        equals( jQuery("component#seite1", xml).length, 1, "Attribute selector with ID" );
+                       equals( jQuery("component", xml).filter("#seite1").length, 1, "Attribute selector filter with ID" );
                        start();
                });
        });
@@ -154,7 +159,7 @@ test("class", function() {
 });
 
 test("name", function() {
-       expect(14);
+       expect(15);
 
        t( "Name selector", "input[name=action]", ["text1"] );
        t( "Name selector with single quotes", "input[name='action']", ["text1"] );
@@ -169,6 +174,12 @@ test("name", function() {
        same( jQuery("#form").find("input[name=action]").get(), q("text1"), "Name selector within the context of another element" );
        same( jQuery("#form").find("input[name='foo[bar]']").get(), q("hidden2"), "Name selector for grouped form element within the context of another element" );
 
+       var form = jQuery("<form><input name='id'/></form>").appendTo("body");
+
+       equals( form.find("input").length, 1, "Make sure that rooted queries on forms (with possible expandos) work." );
+
+       form.remove();
+
        var a = jQuery('<div><a id="tName1ID" name="tName1">tName1 A</a><a id="tName2ID" name="tName2">tName2 A</a><div id="tName1">tName1 Div</div></div>').appendTo('#main').children();
 
        equals( a.length, 3, "Make sure the right number of elements were inserted." );
@@ -199,15 +210,15 @@ test("child and adjacent", function() {
        t( "Child w/ Class", "p > a.blog", ["mark","simon"] );
        t( "All Children", "code > *", ["anchor1","anchor2"] );
        t( "All Grandchildren", "p > * > *", ["anchor1","anchor2"] );
-       t( "Adjacent", "a + a", ["groups"] );
-       t( "Adjacent", "a +a", ["groups"] );
-       t( "Adjacent", "a+ a", ["groups"] );
-       t( "Adjacent", "a+a", ["groups"] );
+       t( "Adjacent", "#main a + a", ["groups"] );
+       t( "Adjacent", "#main a +a", ["groups"] );
+       t( "Adjacent", "#main a+ a", ["groups"] );
+       t( "Adjacent", "#main a+a", ["groups"] );
        t( "Adjacent", "p + p", ["ap","en","sap"] );
        t( "Adjacent", "p#firstp + p", ["ap"] );
        t( "Adjacent", "p[lang=en] + p", ["sap"] );
        t( "Adjacent", "a.GROUPS + code + a", ["mark"] );
-       t( "Comma, Child, and Adjacent", "a + a, code > a", ["groups","anchor1","anchor2"] );
+       t( "Comma, Child, and Adjacent", "#main a + a, code > a", ["groups","anchor1","anchor2"] );
        t( "Element Preceded By", "p ~ div", ["foo", "moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
        t( "Element Preceded By", "#first ~ div", ["moretests","tabindex-tests", "liveHandlerOrder", "siblingTest"] );
        t( "Element Preceded By", "#groups ~ a", ["mark"] );
@@ -226,7 +237,7 @@ test("child and adjacent", function() {
 });
 
 test("attributes", function() {
-       expect(34);
+       expect(39);
        t( "Attribute Exists", "a[title]", ["google"] );
        t( "Attribute Exists", "*[title]", ["google"] );
        t( "Attribute Exists", "[title]", ["google"] );
@@ -264,6 +275,17 @@ test("attributes", function() {
        t( "Attribute Contains", "a[href *= 'google']", ["google","groups"] );
        t( "Attribute Is Not Equal", "#ap a[hreflang!='en']", ["google","groups","anchor1"] );
 
+       var opt = document.getElementById("option1a"),
+               match = (window.Sizzle || window.jQuery.find).matchesSelector;
+
+       opt.setAttribute("test", "");
+
+       ok( match( opt, "[id*=option1][type!=checkbox]" ), "Attribute Is Not Equal Matches" );
+       ok( match( opt, "[id*=option1]" ), "Attribute With No Quotes Contains Matches" );
+       ok( match( opt, "[test=]" ), "Attribute With No Quotes No Content Matches" );
+       ok( match( opt, "[id=option1a]" ), "Attribute With No Quotes Equals Matches" );
+       ok( match( document.getElementById("simon1"), "a[href*=#]" ), "Attribute With No Quotes Href Contains Matches" );
+
        t("Empty values", "#select1 option[value='']", ["option1a"]);
        t("Empty values", "#select1 option[value!='']", ["option1b","option1c","option1d"]);
        
@@ -321,10 +343,13 @@ test("pseudo - child", function() {
 });
 
 test("pseudo - misc", function() {
-       expect(6);
+       expect(7);
 
        t( "Headers", ":header", ["qunit-header", "qunit-banner", "qunit-userAgent"] );
        t( "Has Children - :has()", "p:has(a)", ["firstp","ap","en","sap"] );
+       
+       var select = document.getElementById("select1");
+       ok( (window.Sizzle || window.jQuery.find).matchesSelector( select, ":has(option)" ), "Has Option Matches" );
 
        t( "Text Contains", "a:contains(Google)", ["google","groups"] );
        t( "Text Contains", "a:contains(Google Groups)", ["groups"] );
index f9e7937..0d079f1 100644 (file)
@@ -1,7 +1,7 @@
 module("traversing");
 
 test("find(String)", function() {
-       expect(3);
+       expect(5);
        equals( 'Yahoo', jQuery('#foo').find('.blogTest').text(), 'Check for find' );
 
        // using contents will get comments regular, text, and comment nodes
@@ -9,6 +9,8 @@ test("find(String)", function() {
        equals( j.find("div").length, 0, "Check node,textnode,comment to find zero divs" );
 
        same( jQuery("#main").find("> div").get(), q("foo", "moretests", "tabindex-tests", "liveHandlerOrder", "siblingTest"), "find child elements" );
+       same( jQuery("#main").find("> #foo, > #moretests").get(), q("foo", "moretests"), "find child elements" );
+       same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" );
 });
 
 test("is(String)", function() {
index 3c80e4f..7810cd6 100644 (file)
@@ -1 +1 @@
-1.4.3
\ No newline at end of file
+1.4.5pre
\ No newline at end of file