From: jeresig Date: Thu, 9 Dec 2010 17:51:14 +0000 (-0500) Subject: Merge branch 'explain-map-concat' of https://github.com/ajpiano/jquery into ajpiano... X-Git-Url: http://git.asbjorn.biz/?a=commitdiff_plain;h=bc05cb9d80b63d8a324a3773a39ac1baa181c4d2;hp=34bf1a2a7d688d9861350fd7836eb98268db821e;p=jquery.git Merge branch 'explain-map-concat' of https://github.com/ajpiano/jquery into ajpiano-explain-map-concat --- diff --git a/.gitattributes b/.gitattributes index bcb36db..d6dc470 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -* crlf=input +* eol=lf +*.jar binary diff --git a/Makefile b/Makefile index ce92f4f..0dae732 100644 --- 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} @@ -39,7 +39,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) @@ -97,8 +97,10 @@ min: ${JQ_MIN} ${JQ_MIN}: ${JQ} @@echo "Building" ${JQ_MIN} - @@head -$(shell grep -m 1 -n '*/' ${JQ} | cut -f1 -d:) ${JQ} > ${JQ_MIN} - @@${MINJAR} --js ${JQ} --warning_level QUIET --js_output_file ${JQ_MIN} + @@head -15 ${JQ} > ${JQ_MIN} + @@${MINJAR} --js ${JQ} --warning_level QUIET --js_output_file ${JQ_MIN}.tmp + @@cat ${JQ_MIN}.tmp >> ${JQ_MIN} + @@rm -f ${JQ_MIN}.tmp clean: @@echo "Removing Distribution directory:" ${DIST_DIR} diff --git a/Rakefile b/Rakefile index 38406bd..d0d8f66 100644 --- a/Rakefile +++ b/Rakefile @@ -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 diff --git a/build.xml b/build.xml index e91cdd1..c6be9f9 100644 --- a/build.xml +++ b/build.xml @@ -89,7 +89,7 @@ - + diff --git a/build/google-compiler-20091218.jar b/build/google-compiler-20091218.jar deleted file mode 100644 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 index 0000000..4dfa5ad Binary files /dev/null and b/build/google-compiler-20100917.jar differ diff --git a/build/jslint-check.js b/build/jslint-check.js index e76abc0..976975a 100644 --- a/build/jslint-check.js +++ b/build/jslint-check.js @@ -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; diff --git a/speed/benchmark.js b/speed/benchmark.js index 8f1aa98..50d5cad 100644 --- a/speed/benchmark.js +++ b/speed/benchmark.js @@ -1,9 +1,15 @@ // Runs a function many times without the function call overhead -function benchmark(fn, times){ +function benchmark(fn, times, name){ fn = fn.toString(); var s = fn.indexOf('{')+1, e = fn.lastIndexOf('}'); fn = fn.substring(s,e); - return new Function('i','var t=new Date;while(i--){'+fn+'};return new Date-t')(times); + return benchmarkString(fn, times, name); +} + +function benchmarkString(fn, times, name) { + var fn = new Function("i", "var t=new Date; while(i--) {" + fn + "}; return new Date - t")(times) + fn.displayName = name || "benchmarked"; + return fn; } diff --git a/speed/closest.html b/speed/closest.html new file mode 100644 index 0000000..bb31f5d --- /dev/null +++ b/speed/closest.html @@ -0,0 +1,39 @@ + + + + Test .closest() Performance + + + + + + + +
+

Hello

+
+
+

lorem ipsum

+

dolor sit amet

+
+
+
+
    + + + diff --git a/speed/filter.html b/speed/filter.html new file mode 100644 index 0000000..43ee94e --- /dev/null +++ b/speed/filter.html @@ -0,0 +1,183 @@ + + + + Test .filter() Performance + + + + + + + +
    +

    Hello

    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
      + + + diff --git a/speed/find.html b/speed/find.html new file mode 100644 index 0000000..d3a2dc1 --- /dev/null +++ b/speed/find.html @@ -0,0 +1,179 @@ + + + + Test .find() Performance + + + + + + + +
      +

      Hello

      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
      +
        + + + diff --git a/src/ajax.js b/src/ajax.js index 31efc56..90dc350 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -4,7 +4,7 @@ var jsc = jQuery.now(), rscript = /)<[^<]*)*<\/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)$/, + rnoContent = /^(?:GET|HEAD)$/, rbracket = /\[\]$/, jsre = /\=\?(&|$)/, rquery = /\?/, @@ -180,19 +180,10 @@ jQuery.extend({ password: null, traditional: false, */ - // Create the request object; Microsoft failed to properly - // implement the XMLHttpRequest in IE7 (can't request local files), - // so we use the ActiveXObject when it is available // This function can be overriden by calling jQuery.ajaxSetup - xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ? - function() { - return new window.XMLHttpRequest(); - } : - function() { - try { - return new window.ActiveXObject("Microsoft.XMLHTTP"); - } catch(e) {} - }, + xhr: function() { + return new window.XMLHttpRequest(); + }, accepts: { xml: "application/xml, text/xml", html: "text/html", @@ -204,10 +195,24 @@ jQuery.extend({ }, ajax: function( origSettings ) { + // IE8 leaks a lot when we've set abort, and IE6-8 a little + // when we have set onreadystatechange. Bug #6242 + // XXX IE7 still leaks when abort is called, no matter what + // we do + function cleanup() { + // IE6 will throw an error setting xhr.abort + try { + xhr.abort = xhr.onreadystatechange = jQuery.noop; + } catch(e) {} + } + 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, "" ); + // toString fixes people passing a window.location or + // document.location to $.ajax, which worked in 1.4.2 and + // earlier (bug #7531). It should be removed in 1.5. + 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; @@ -248,10 +253,6 @@ jQuery.extend({ 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 ); @@ -263,6 +264,10 @@ jQuery.extend({ delete window[ jsonp ]; } catch( jsonpError ) {} } + + data = tmp; + jQuery.handleSuccess( s, xhr, status, data ); + jQuery.handleComplete( s, xhr, status, data ); if ( head ) { head.removeChild( script ); @@ -270,11 +275,11 @@ jQuery.extend({ }; } - if ( s.dataType === "script" && s.cache === null ) { + if ( s.dataType === "script" && s.cache === undefined ) { s.cache = false; } - if ( s.cache === false && type === "GET" ) { + if ( s.cache === false && noContent ) { var ts = jQuery.now(); // try replacing _= if it is there @@ -284,19 +289,19 @@ jQuery.extend({ 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" ) { + // If data is available, append data to url for GET/HEAD requests + if ( s.data && noContent ) { s.url += (rquery.test(s.url) ? "&" : "?") + s.data; } // Watch for a new set of requests - if ( s.global && jQuery.ajax.active++ === 0 ) { + if ( s.global && jQuery.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); + remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host); // If we're requesting a remote document // and trying to load JSON or Script with a GET @@ -317,8 +322,8 @@ jQuery.extend({ 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 ); + jQuery.handleSuccess( s, xhr, status, data ); + jQuery.handleComplete( s, xhr, status, data ); // Handle memory leak in IE script.onload = script.onreadystatechange = null; @@ -367,8 +372,8 @@ jQuery.extend({ 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 ( jQuery.etag[s.url] ) { + xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]); } } @@ -387,7 +392,7 @@ jQuery.extend({ // 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 ) { + if ( s.global && jQuery.active-- === 1 ) { jQuery.event.trigger( "ajaxStop" ); } @@ -397,7 +402,7 @@ jQuery.extend({ } if ( s.global ) { - jQuery.ajax.triggerGlobal( s, "ajaxSend", [xhr, s] ); + jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] ); } // Wait for a response to come back @@ -407,24 +412,23 @@ jQuery.extend({ // Opera doesn't call onreadystatechange before this point // so we simulate the call if ( !requestDone ) { - jQuery.ajax.handleComplete( s, xhr, status, data ); + jQuery.handleComplete( s, xhr, status, data ); } requestDone = true; if ( xhr ) { - xhr.onreadystatechange = jQuery.noop; + cleanup(); } // 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 ) ? + !jQuery.httpSuccess( xhr ) ? "error" : - s.ifModified && jQuery.ajax.httpNotModified( xhr, s.url ) ? + s.ifModified && jQuery.httpNotModified( xhr, s.url ) ? "notmodified" : "success"; @@ -434,7 +438,7 @@ jQuery.extend({ // 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 ); + data = jQuery.httpData( xhr, s.dataType, s ); } catch( parserError ) { status = "parsererror"; errMsg = parserError; @@ -445,35 +449,35 @@ jQuery.extend({ if ( status === "success" || status === "notmodified" ) { // JSONP handles its own success callback if ( !jsonp ) { - jQuery.ajax.handleSuccess( s, xhr, status, data ); + jQuery.handleSuccess( s, xhr, status, data ); } } else { - jQuery.ajax.handleError( s, xhr, status, errMsg ); + jQuery.handleError( s, xhr, status, errMsg ); } // Fire the complete handlers if ( !jsonp ) { - jQuery.ajax.handleComplete( s, xhr, status, data ); + jQuery.handleComplete( s, xhr, status, data ); } if ( isTimeout === "timeout" ) { xhr.abort(); } - // Stop memory leaks - if ( s.async ) { - xhr = null; - } + cleanup(); } }; - // Override the abort handler, if we can (IE doesn't allow it, but that's OK) + // 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() { if ( xhr ) { - oldAbort.call( xhr ); + // oldAbort has no call property in IE7 so + // just do it this way, which works in all + // browsers + Function.prototype.call.call( oldAbort, xhr ); } onreadystatechange( "abort" ); @@ -495,10 +499,10 @@ jQuery.extend({ xhr.send( noContent || s.data == null ? null : s.data ); } catch( sendError ) { - jQuery.ajax.handleError( s, xhr, null, sendError ); + jQuery.handleError( s, xhr, null, sendError ); // Fire the complete handlers - jQuery.ajax.handleComplete( s, xhr, status, data ); + jQuery.handleComplete( s, xhr, status, data ); } // firefox 1.5 doesn't fire statechange for sync requests @@ -513,11 +517,12 @@ jQuery.extend({ // 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 ) { @@ -581,7 +586,9 @@ 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, @@ -598,7 +605,7 @@ jQuery.extend( jQuery.ajax, { // Fire the global callback if ( s.global ) { - jQuery.ajax.triggerGlobal( s, "ajaxError", [xhr, s, e] ); + jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] ); } }, @@ -610,7 +617,7 @@ jQuery.extend( jQuery.ajax, { // Fire the global callback if ( s.global ) { - jQuery.ajax.triggerGlobal( s, "ajaxSuccess", [xhr, s] ); + jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] ); } }, @@ -622,11 +629,11 @@ jQuery.extend( jQuery.ajax, { // The request was completed if ( s.global ) { - jQuery.ajax.triggerGlobal( s, "ajaxComplete", [xhr, s] ); + jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] ); } // Handle the global AJAX counter - if ( s.global && jQuery.ajax.active-- === 1 ) { + if ( s.global && jQuery.active-- === 1 ) { jQuery.event.trigger( "ajaxStop" ); } }, @@ -653,11 +660,11 @@ jQuery.extend( jQuery.ajax, { etag = xhr.getResponseHeader("Etag"); if ( lastModified ) { - jQuery.ajax.lastModified[url] = lastModified; + jQuery.lastModified[url] = lastModified; } if ( etag ) { - jQuery.ajax.etag[url] = etag; + jQuery.etag[url] = etag; } return xhr.status === 304; @@ -695,10 +702,28 @@ jQuery.extend( jQuery.ajax, { }); +/* + * Create the request object; Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ +if ( window.ActiveXObject ) { + jQuery.ajaxSettings.xhr = function() { + if ( window.location.protocol !== "file:" ) { + try { + return new window.XMLHttpRequest(); + } catch(xhrError) {} + } + + try { + return new window.ActiveXObject("Microsoft.XMLHTTP"); + } catch(activeError) {} + }; +} + // Does this browser support XHR requests? jQuery.support.ajax = !!jQuery.ajaxSettings.xhr(); -// For backwards compatibility -jQuery.extend( jQuery.ajax ); - })( jQuery ); diff --git a/src/attributes.js b/src/attributes.js index cb9f2cf..78b1bfd 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -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, ""); @@ -215,6 +232,10 @@ jQuery.fn.extend({ val = ""; } else if ( typeof val === "number" ) { val += ""; + } else if ( jQuery.isArray(val) ) { + val = jQuery.map(val, function (value) { + return value == null ? "" : value + ""; + }); } if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { @@ -249,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; } @@ -278,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; @@ -295,7 +316,14 @@ jQuery.extend({ jQuery.error( "type property can't be changed" ); } - elem[ name ] = value; + if ( value === null ) { + if ( elem.nodeType === 1 ) { + elem.removeAttribute( name ); + } + + } else { + elem[ name ] = value; + } } // browsers index elements by id/name on forms, give priority to attributes. @@ -345,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 ]; } }); diff --git a/src/core.js b/src/core.js index 3c7572f..008a88c 100644 --- a/src/core.js +++ b/src/core.js @@ -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" ); + } } } }, @@ -526,6 +532,12 @@ jQuery.extend({ }, isEmptyObject: function( obj ) { + + // Fixes #7413 Check to see if obj passes isPlainObject + if ( !jQuery.isPlainObject( obj ) ) { + return false; + } + for ( var name in obj ) { return false; } @@ -678,7 +690,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++ ) { diff --git a/src/css.js b/src/css.js index 07ff686..8a83c60 100644 --- a/src/css.js +++ b/src/css.js @@ -1,6 +1,6 @@ (function( jQuery ) { -var ralpha = /alpha\([^)]*\)/, +var ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, rdashAlpha = /-([a-z])/ig, rupper = /([A-Z])/g, @@ -12,14 +12,19 @@ var ralpha = /alpha\([^)]*\)/, cssHeight = [ "Top", "Bottom" ], curCSS, - // cache check for defaultView.getComputedStyle - getComputedStyle = document.defaultView && document.defaultView.getComputedStyle, + getComputedStyle, + currentStyle, fcamelCase = function( all, letter ) { return letter.toUpperCase(); }; jQuery.fn.css = function( name, value ) { + // Setting 'undefined' is a no-op + if ( arguments.length === 2 && value === undefined ) { + return this; + } + return jQuery.access( this, name, value, true, function( elem, name, value ) { return value !== undefined ? jQuery.style( elem, name, value ) : @@ -65,7 +70,7 @@ jQuery.extend({ style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { - return undefined; + return; } // Make sure that we're working with the right name @@ -76,6 +81,11 @@ jQuery.extend({ // Check if we're setting a value if ( value !== undefined ) { + // Make sure that NaN and null values aren't set. See: #7116 + if ( typeof value === "number" && isNaN( value ) || value == null ) { + return; + } + // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; @@ -83,7 +93,11 @@ jQuery.extend({ // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { - style[ name ] = value; + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} } } else { @@ -155,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"; } }, @@ -199,13 +235,13 @@ if ( !jQuery.support.opacity ) { style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : - opacity; + style.filter + ' ' + 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(); @@ -216,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 @@ -245,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; @@ -275,14 +319,10 @@ function getWH( elem, name, extra ) { if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.hidden = function( elem ) { - var width = elem.offsetWidth, height = elem.offsetHeight, - skip = elem.nodeName.toLowerCase() === "tr"; - - return width === 0 && height === 0 && !skip ? - true : - width > 0 && height > 0 && !skip ? - false : - (elem.style.display || jQuery.css( elem, "display" )) === "none"; + var width = elem.offsetWidth, + height = elem.offsetHeight; + + return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none"); }; jQuery.expr.filters.visible = function( elem ) { diff --git a/src/data.js b/src/data.js index 43ab595..f1e031f 100644 --- a/src/data.js +++ b/src/data.js @@ -30,18 +30,17 @@ jQuery.extend({ windowData : elem; - var id = elem[ jQuery.expando ], cache = jQuery.cache, thisCache, - isNode = elem.nodeType, - store; + var isNode = elem.nodeType, + id = isNode ? elem[ jQuery.expando ] : null, + cache = jQuery.cache, thisCache; - if ( !id && typeof name === "string" && data === undefined ) { + if ( isNode && !id && typeof name === "string" && data === undefined ) { return; } // Get the data from the object directly if ( !isNode ) { cache = elem; - id = jQuery.expando; // Compute a unique ID for the element } else if ( !id ) { @@ -55,26 +54,14 @@ jQuery.extend({ cache[ id ] = jQuery.extend(cache[ id ], name); } else { - store = jQuery.extend(cache[ id ], name); - cache[ id ] = function() { - return store; - }; + jQuery.extend( cache, name ); } - } else if ( !cache[ id ] ) { - if ( isNode ) { - cache[ id ] = {}; - - } else { - store = {}; - cache[ id ] = function() { - return store; - }; - } - + } else if ( isNode && !cache[ id ] ) { + cache[ id ] = {}; } - thisCache = isNode ? cache[ id ] : cache[ id ](); + thisCache = isNode ? cache[ id ] : cache; // Prevent overriding the named cache with undefined values if ( data !== undefined ) { @@ -94,11 +81,9 @@ jQuery.extend({ elem; var isNode = elem.nodeType, - id = elem[ jQuery.expando ], cache = jQuery.cache; - if ( id && !isNode ) { - id = id(); - } - var thisCache = cache[ id ]; + id = isNode ? elem[ jQuery.expando ] : elem, + cache = jQuery.cache, + thisCache = isNode ? cache[ id ] : id; // If we want to remove a specific section of the element's data if ( name ) { @@ -107,23 +92,28 @@ jQuery.extend({ delete thisCache[ name ]; // If we've removed all the data, remove the element's cache - if ( jQuery.isEmptyObject(thisCache) ) { + if ( isNode && jQuery.isEmptyObject(thisCache) ) { jQuery.removeData( elem ); } } // Otherwise, we want to remove all of the element's data } else { - if ( jQuery.support.deleteExpando || !isNode ) { + if ( isNode && jQuery.support.deleteExpando ) { delete elem[ jQuery.expando ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( jQuery.expando ); - } // Completely remove the data cache - if ( isNode ) { + } else if ( isNode ) { delete cache[ id ]; + + // Remove all fields from the object + } else { + for ( var n in elem ) { + delete elem[ n ]; + } } } }, @@ -131,7 +121,7 @@ jQuery.extend({ // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { if ( elem.nodeName ) { - match = jQuery.noData[ elem.nodeName.toLowerCase() ]; + var match = jQuery.noData[ elem.nodeName.toLowerCase() ]; if ( match ) { return !(match === true || elem.getAttribute("classid") !== match); @@ -144,8 +134,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() { @@ -157,31 +165,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] ? @@ -190,7 +179,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 ); @@ -206,4 +196,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 ); diff --git a/src/dimensions.js b/src/dimensions.js index 5aafbf4..f35b0ac 100644 --- a/src/dimensions.js +++ b/src/dimensions.js @@ -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" ); + } }; }); diff --git a/src/effects.js b/src/effects.js index 56141bb..067383b 100644 --- a/src/effects.js +++ b/src/effects.js @@ -2,7 +2,7 @@ var elemdisplay = {}, rfxtypes = /^(?:toggle|show|hide)$/, - rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/, + rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, timerId, fxAttrs = [ // height animations @@ -15,43 +15,39 @@ var elemdisplay = {}, jQuery.fn.extend({ show: function( speed, easing, callback ) { - if ( speed || speed === 0) { + var elem, display; + + if ( speed || speed === 0 ) { return this.animate( genFx("show", 3), speed, easing, callback); } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - var old = jQuery.data(this[i], "olddisplay"); - - this[i].style.display = old || ""; - - if ( jQuery.css( this[i], "display" ) === "none" ) { - var nodeName = this[i].nodeName, display; - - if ( elemdisplay[ nodeName ] ) { - display = elemdisplay[ nodeName ]; - - } else { - var elem = jQuery("<" + nodeName + ">").appendTo("body"); - - display = elem.css("display"); - - if ( display === "none" ) { - display = "block"; - } - - elem.remove(); - - elemdisplay[ nodeName ] = display; - } + 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(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } - jQuery.data(this[i], "olddisplay", 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 ( display === "" && jQuery.css( elem, "display" ) === "none" ) { + jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName)); } } - // Set the display of the elements in a second loop + // Set the display of most of the elements in a second loop // to avoid the constant reflow - for ( var j = 0, k = this.length; j < k; j++ ) { - this[j].style.display = jQuery.data(this[j], "olddisplay") || ""; + for ( i = 0; i < j; i++ ) { + elem = this[i]; + display = elem.style.display; + + if ( display === "" || display === "none" ) { + elem.style.display = jQuery.data(elem, "olddisplay") || ""; + } } return this; @@ -63,17 +59,18 @@ jQuery.fn.extend({ return this.animate( genFx("hide", 3), speed, easing, callback); } else { - for ( var i = 0, l = this.length; i < l; i++ ) { - var old = jQuery.data(this[i], "olddisplay"); - if ( !old && old !== "none" ) { - jQuery.data( this[i], "olddisplay", jQuery.css( this[i], "display" ) ); + for ( var i = 0, j = this.length; i < j; i++ ) { + var display = jQuery.css( this[i], "display" ); + + if ( display !== "none" ) { + jQuery.data( this[i], "olddisplay", display ); } } // Set the display of the elements in a second loop // to avoid the constant reflow - for ( var j = 0, k = this.length; j < k; j++ ) { - this[j].style.display = "none"; + for ( i = 0; i < j; i++ ) { + this[i].style.display = "none"; } return this; @@ -115,8 +112,12 @@ jQuery.fn.extend({ } return this[ optall.queue === false ? "each" : "queue" ](function() { + // XXX 'this' does not always have a nodeName when running the + // test suite + var opt = jQuery.extend({}, optall), p, - hidden = this.nodeType === 1 && jQuery(this).is(":hidden"), + isElement = this.nodeType === 1, + hidden = isElement && jQuery(this).is(":hidden"), self = this; for ( p in prop ) { @@ -132,12 +133,35 @@ jQuery.fn.extend({ return opt.complete.call(this); } - if ( ( p === "height" || p === "width" ) && this.style ) { - // Store display property - opt.display = this.style.display; - + if ( isElement && ( p === "height" || p === "width" ) ) { // Make sure that nothing sneaks out - opt.overflow = this.style.overflow; + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height + // animated + if ( jQuery.css( this, "display" ) === "inline" && + jQuery.css( this, "float" ) === "none" ) { + if ( !jQuery.support.inlineBlockNeedsLayout ) { + this.style.display = "inline-block"; + + } else { + var display = defaultDisplay(this.nodeName); + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( display === "inline" ) { + this.style.display = "inline-block"; + + } else { + this.style.display = "inline"; + this.style.zoom = 1; + } + } + } } if ( jQuery.isArray( prop[p] ) ) { @@ -161,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] ), @@ -169,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 @@ -239,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 ); @@ -303,11 +328,6 @@ jQuery.fx.prototype = { } (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); - - // Set display property to block for height/width animations - if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) { - this.elem.style.display = "block"; - } }, // Get the current size @@ -322,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; @@ -329,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); } @@ -384,17 +406,14 @@ jQuery.fx.prototype = { } if ( done ) { - if ( this.options.display != null ) { - // Reset the overflow - this.elem.style.overflow = this.options.overflow; - - // Reset the display - var old = jQuery.data(this.elem, "olddisplay"); - this.elem.style.display = old ? old : this.options.display; - - if ( jQuery.css( this.elem, "display" ) === "none" ) { - this.elem.style.display = "block"; - } + // Reset the overflow + if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { + var elem = this.elem, + options = this.options; + + jQuery.each( [ "", "X", "Y" ], function (index, value) { + elem.style[ "overflow" + value ] = options.overflow[index]; + } ); } // Hide the element if the "hide" operation was done @@ -447,14 +466,14 @@ jQuery.extend( jQuery.fx, { jQuery.fx.stop(); } }, - + interval: 13, - + stop: function() { clearInterval( timerId ); timerId = null; }, - + speeds: { slow: 600, fast: 200, @@ -485,4 +504,21 @@ if ( jQuery.expr && jQuery.expr.filters ) { }; } +function defaultDisplay( nodeName ) { + if ( !elemdisplay[ nodeName ] ) { + var elem = jQuery("<" + nodeName + ">").appendTo("body"), + display = elem.css("display"); + + elem.remove(); + + if ( display === "none" || display === "" ) { + display = "block"; + } + + elemdisplay[ nodeName ] = display; + } + + return elemdisplay[ nodeName ]; +} + })( jQuery ); diff --git a/src/event.js b/src/event.js index 65b5952..fd470e7 100644 --- a/src/event.js +++ b/src/event.js @@ -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,8 +58,28 @@ jQuery.event = { return; } - var events = elemData.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" ) { + // On plain objects events is a fn that holds the the data + // which prevents this data from being JSON serialized + // the function does not need to be called, it just contains the data + eventHandle = events.handle; + events = events.events; + + } else if ( !events ) { + 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[ eventKey ] = elemData = function(){}; + } + + elemData.events = events = {}; + } if ( !eventHandle ) { elemData.handle = eventHandle = function() { @@ -153,12 +177,18 @@ 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; } + + if ( typeof events === "function" ) { + elemData = events; + events = events.events; + } // types is actually an event object here if ( types && types.type ) { @@ -259,7 +289,10 @@ jQuery.event = { delete elemData.events; delete elemData.handle; - if ( jQuery.isEmptyObject( elemData ) ) { + if ( typeof elemData === "function" ) { + jQuery.removeData( elem, eventKey ); + + } else if ( jQuery.isEmptyObject( elemData ) ) { jQuery.removeData( elem ); } } @@ -319,7 +352,10 @@ jQuery.event = { event.currentTarget = elem; // Trigger the event, it is assumed that "handle" is a function - var handle = jQuery.data( elem, "handle" ); + var handle = elem.nodeType ? + jQuery.data( elem, "handle" ) : + (jQuery.data( elem, "__events__" ) || {}).handle; + if ( handle ) { handle.apply( elem, data ); } @@ -342,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) && @@ -375,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; @@ -392,7 +432,12 @@ 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; + } + handlers = (events || {})[ event.type ]; if ( events && handlers ) { @@ -449,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) @@ -464,14 +510,16 @@ 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); } // Add which for key events - if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) { - event.which = event.charCode || event.keyCode; + if ( event.which == null && (event.charCode != null || event.keyCode != null) ) { + event.which = event.charCode != null ? event.charCode : event.keyCode; } // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) @@ -668,19 +716,23 @@ 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; return trigger( "submit", this, arguments ); } }); 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; return trigger( "submit", this, arguments ); } }); @@ -743,6 +795,7 @@ if ( !jQuery.support.changeBubbles ) { if ( data != null || val ) { e.type = "change"; + e.liveFired = undefined; return jQuery.event.trigger( e, arguments[1], elem ); } }; @@ -751,6 +804,8 @@ if ( !jQuery.support.changeBubbles ) { filters: { focusout: testChange, + beforedeactivate: testChange, + click: function( e ) { var elem = e.target, type = elem.type; @@ -773,7 +828,7 @@ if ( !jQuery.support.changeBubbles ) { // Beforeactivate happens also before the previous element is blurred // with this event you can't trigger a change event, but you can store - // information/focus[in] is not needed anymore + // information beforeactivate: function( e ) { var elem = e.target; jQuery.data( elem, "_change_data", getVal(elem) ); @@ -800,6 +855,9 @@ if ( !jQuery.support.changeBubbles ) { }; changeFilters = jQuery.event.special.change.filters; + + // Handle when the input is .focus()'d + changeFilters.focus = changeFilters.beforeactivate; } function trigger( type, elem, args ) { @@ -812,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 ); } }); } @@ -908,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 ) { @@ -1003,15 +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__" ); - // Make sure we avoid non-left-click bubbling in Firefox (#3861) - if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) { - return; + if ( typeof events === "function" ) { + events = events.events; } + // 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("\\.(?:.*\\.)?") + "(\\.|$)"); } @@ -1075,6 +1143,9 @@ function liveHandler( event ) { if ( ret === false ) { stop = false; } + if ( event.isImmediatePropagationStopped() ) { + break; + } } } @@ -1111,7 +1182,7 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl // More info: // - http://isaacschlueter.com/2006/10/msie-memory-leaks/ if ( window.attachEvent && !window.addEventListener ) { - window.attachEvent("onunload", function() { + jQuery(window).bind("unload", function() { for ( var id in jQuery.cache ) { if ( jQuery.cache[ id ].handle ) { // Try/Catch is to handle iframes being unloaded, see #4280 diff --git a/src/manipulation.js b/src/manipulation.js index 00e3120..8d951b6 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -7,8 +7,11 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rtbody = /\s]+\/)>/g, + rbodystart = /^\s*\s*$/i, wrapMap = { option: [ 1, "" ], legend: [ 1, "
        ", "
        " ], @@ -33,7 +36,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 +86,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 +151,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 +166,7 @@ jQuery.fn.extend({ } } } - + return this; }, @@ -177,7 +182,7 @@ jQuery.fn.extend({ elem.removeChild( elem.firstChild ); } } - + return this; }, @@ -193,11 +198,14 @@ jQuery.fn.extend({ // 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; + var html = this.outerHTML, + ownerDocument = this.ownerDocument; if ( !html ) { var div = ownerDocument.createElement("div"); div.appendChild( this.cloneNode(true) ); html = div.innerHTML; + } else if ( rbodystart.test(html) && rbodyend.test(html) ) { + html = html.replace( rbodystart, "
        " ).replace( rbodyend, "
        " ); } return jQuery.clean([html.replace(rinlinejQuery, "") @@ -248,10 +256,9 @@ jQuery.fn.extend({ } else if ( jQuery.isFunction( value ) ) { this.each(function(i){ - var self = jQuery(this), old = self.html(); - self.empty().append(function(){ - return value.call( this, i, old ); - }); + var self = jQuery( this ); + + self.html( value.call(this, i, self.html()) ); }); } else { @@ -273,13 +280,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 ); @@ -297,7 +305,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 ) ) { @@ -324,9 +334,9 @@ jQuery.fn.extend({ } else { results = jQuery.buildFragment( args, this, scripts ); } - + fragment = results.fragment; - + if ( fragment.childNodes.length === 1 ) { first = fragment = fragment.firstChild; } else { @@ -342,7 +352,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 ); } @@ -372,7 +382,9 @@ function cloneCopyEvent(orig, ret) { return; } - var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events; + var oldData = jQuery.data( orig[i++] ), + curData = jQuery.data( this, oldData ), + events = oldData && oldData.events; if ( events ) { delete curData.handle; @@ -429,20 +441,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 ); } }; @@ -530,7 +543,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"))) ); @@ -542,22 +555,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 ] ) { @@ -568,14 +581,14 @@ jQuery.extend({ } } } - + if ( deleteExpando ) { delete elem[ jQuery.expando ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( jQuery.expando ); } - + delete cache[ id ]; } } diff --git a/src/offset.js b/src/offset.js index 650cc08..3fb2917 100644 --- a/src/offset.js +++ b/src/offset.js @@ -5,7 +5,7 @@ var rtable = /^t(?:able|d|h)$/i, if ( "getBoundingClientRect" in document.documentElement ) { jQuery.fn.offset = function( options ) { - var elem = this[0]; + var elem = this[0], box; if ( options ) { return this.each(function( i ) { @@ -21,10 +21,19 @@ if ( "getBoundingClientRect" in document.documentElement ) { return jQuery.offset.bodyOffset( elem ); } - var box = elem.getBoundingClientRect(), - doc = elem.ownerDocument, - body = doc.body, - docElem = doc.documentElement, + try { + box = elem.getBoundingClientRect(); + } catch(e) {} + + 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 body = doc.body, win = getWindow(doc), clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0, @@ -56,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" ) { @@ -142,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(); diff --git a/src/queue.js b/src/queue.js index 23d4360..735b0e1 100644 --- a/src/queue.js +++ b/src/queue.js @@ -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" ) { diff --git a/src/support.js b/src/support.js index d35dbed..67b41c4 100644 --- a/src/support.js +++ b/src/support.js @@ -61,11 +61,15 @@ optSelected: opt.selected, // Will be defined later + deleteExpando: true, optDisabled: false, checkClone: false, scriptEval: false, noCloneEvent: true, - boxModel: null + boxModel: null, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableHiddenOffsets: true }; // Make sure that the options inside disabled selects aren't marked as disabled @@ -88,6 +92,15 @@ 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 ) { @@ -117,44 +130,67 @@ document.body.appendChild( div ); jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; - document.body.removeChild( div ).style.display = 'none'; - div = null; + + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
        "; + jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; + } + + div.innerHTML = "
        t
        "; + var tds = div.getElementsByTagName("td"); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; + + tds[0].style.display = ""; + tds[1].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; + div.innerHTML = ""; + + document.body.removeChild( div ).style.display = "none"; + div = tds = null; }); // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - var eventSupported = function( eventName ) { - var el = document.createElement("div"); - eventName = "on" + eventName; - - var isSupported = (eventName in el); - if ( !isSupported ) { - el.setAttribute(eventName, "return;"); - isSupported = typeof el[eventName] === "function"; - } - el = null; - - return isSupported; + var eventSupported = function( eventName ) { + var el = document.createElement("div"); + eventName = "on" + eventName; + + var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; + + return isSupported; }; - + jQuery.support.submitBubbles = eventSupported("submit"); jQuery.support.changeBubbles = eventSupported("change"); // 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/traversing.js b/src/traversing.js index dff1087..15446bd 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -5,11 +5,13 @@ var runtil = /Until$/, // Note: This RegExp should be improved, or likely pulled from Sizzle rmultiselector = /,/, isSimple = /^.[^:#\[\.,]*$/, - slice = Array.prototype.slice; + slice = Array.prototype.slice, + POS = jQuery.expr.match.POS; jQuery.fn.extend({ find: function( selector ) { - 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; @@ -55,14 +57,15 @@ jQuery.fn.extend({ }, closest: function( selectors, context ) { - var ret; + var ret = [], i, l, cur = this[0]; if ( jQuery.isArray( selectors ) ) { - var cur = this[0], match, matches = {}, selector, level = 1; - ret = []; + var match, selector, + matches = {}, + level = 1; if ( cur && selectors.length ) { - for ( var i = 0, l = selectors.length; i < l; i++ ) { + for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; if ( !matches[selector] ) { @@ -89,21 +92,26 @@ jQuery.fn.extend({ return ret; } - var pos = jQuery.expr.match.POS.test( selectors ) ? + var pos = POS.test( selectors ) ? jQuery( selectors, context || this.context ) : null; - ret = jQuery.map(this.get(),function( cur,i ) { - while ( cur && cur.ownerDocument && cur !== context ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) { - return cur; - } + for ( i = 0, l = this.length; i < l; i++ ) { + cur = this[i]; + + while ( cur ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; - cur = cur.parentNode; + } else { + cur = cur.parentNode; + if ( !cur || !cur.ownerDocument || cur === context ) { + break; + } + } } + } - return null; - }); - ret = ret.length > 1 ? jQuery.unique(ret) : ret; return this.pushStack( ret, "closest", selectors ); @@ -214,11 +222,15 @@ jQuery.extend({ expr = ":not(" + expr + ")"; } - return jQuery.find.matches(expr, elems); + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); }, 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/test/data/testsuite.css b/test/data/testsuite.css index 1846892..cffaaa4 100644 --- a/test/data/testsuite.css +++ b/test/data/testsuite.css @@ -102,6 +102,8 @@ div.chain.test div { background: green; } div.chain.out { background: green; } div.chain.out div { background: red; display: none; } +/* tests to ensure jQuery can determine the native display mode of elements + that have been set as display: none in stylesheets */ div#show-tests * { display: none; } #nothiddendiv { font-size: 16px; } diff --git a/test/data/text.php b/test/data/text.php index c06ef4b..b9df4cf 100644 --- a/test/data/text.php +++ b/test/data/text.php @@ -1,12 +1,12 @@ -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. +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/delegatetest.html b/test/delegatetest.html index b2840c1..327085c 100644 --- a/test/delegatetest.html +++ b/test/delegatetest.html @@ -1,242 +1,242 @@ - - - - - - -

        Change Tests

        - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        - Change each: - - - - - - - -
        - - - - -
        - -
        - - - - -
        - - - - - - - $(document).bind('change')
        Live:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
        Bind:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
        Focusin:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
        Focusout:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
        Live Focus:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
        Live Blur:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
        -

        Submit Tests

        - - - - - - - - - - - - - - - -
        - Submit each: - -
        - -
        -
        -
        - -
        -
        -
        - -
        -
        $(document).bind('submit')
        Results:TEXTPASSWORDBUTTONDOCUMENT
        - -
          - - - - + + + + + + +

          Change Tests

          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + Change each: + + + + + + + +
          + + + + +
          + +
          + + + + +
          + + + + + + + $(document).bind('change')
          Live:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
          Bind:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
          Focusin:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
          Focusout:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREADOCUMENT
          Live Focus:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
          Live Blur:SELECTMULTICHECKBOXRADIOFILETEXTTEXTAREA
          +

          Submit Tests

          + + + + + + + + + + + + + + + +
          + Submit each: + +
          + +
          +
          +
          + +
          +
          +
          + +
          +
          $(document).bind('submit')
          Results:TEXTPASSWORDBUTTONDOCUMENT
          + +
            + + + + diff --git a/test/index.html b/test/index.html index 5650a1d..e668727 100644 --- a/test/index.html +++ b/test/index.html @@ -48,20 +48,20 @@

              - +
              -