From a95f35744aff95a446cc05e1d8c558b3a4867836 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Fri, 4 Jan 2013 17:33:16 -0500 Subject: [PATCH 01/80] Fix #12945. Check for .getAttribute so IE9 is happy. --- src/attributes.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/attributes.js b/src/attributes.js index 4193bbffb2..754a35e879 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -330,7 +330,11 @@ jQuery.extend({ } else { - ret = elem.getAttribute( name ); + // In IE9+, Flash objects don't have .getAttribute (#12945) + // Support: IE9+ + if ( typeof elem.getAttribute !== "undefined" ) { + ret = elem.getAttribute( name ); + } // Non-existent attributes return null, we normalize to undefined return ret == null ? From b45c775ca971afab0c915fbc91aa8720a639f5d1 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sun, 6 Jan 2013 12:01:22 -0500 Subject: [PATCH 02/80] Fix #12471. Use consistent line endings in jquery.js --- Gruntfile.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index ea51d180a8..0c2c8bb93b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -189,8 +189,8 @@ module.exports = function( grunt ) { grunt.verbose.write("Injected sizzle-jquery.js into sizzle.js"); - // Write concatenated source to file - grunt.file.write( name, compiled ); + // Write concatenated source to file, and ensure newline-only termination + grunt.file.write( name, compiled.replace( /\x0d\x0a/g, "\x0a" ) ); // Fail task if errors were logged. if ( this.errorCount ) { @@ -409,8 +409,16 @@ module.exports = function( grunt ) { nonascii = false; distpaths.forEach(function( filename ) { - var text = fs.readFileSync( filename, "utf8" ), - i, c; + var i, c, + text = fs.readFileSync( filename, "utf8" ); + + // Ensure files use only \n for line endings, not \r\n + if ( /\x0d\x0a/.test( text ) ) { + grunt.log.writeln( filename + ": Incorrect line endings (\\r\\n)" ); + nonascii = true; + } + + // Ensure only ASCII chars so script tags don't need a charset attribute if ( text.length !== Buffer.byteLength( text, "utf8" ) ) { grunt.log.writeln( filename + ": Non-ASCII characters detected:" ); for ( i = 0; i < text.length; i++ ) { @@ -418,10 +426,10 @@ module.exports = function( grunt ) { if ( c > 127 ) { grunt.log.writeln( "- position " + i + ": " + c ); grunt.log.writeln( "-- " + text.substring( i - 20, i + 20 ) ); - nonascii = true; break; } } + nonascii = true; } // Modify map so that it points to files in the same folder; From bbdf957e9886212cac9b72ee9dedd73118aa8427 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sun, 6 Jan 2013 14:20:35 -0500 Subject: [PATCH 03/80] Fix #12336. Ensure oldIE really does .empty() selects. --- src/manipulation.js | 6 ++++++ test/unit/manipulation.js | 10 ++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 5fec948cb4..e8c0fe46f9 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -192,6 +192,12 @@ jQuery.fn.extend({ while ( elem.firstChild ) { elem.removeChild( elem.firstChild ); } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } } return this; diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 86b26e040c..d208b3b7a9 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1829,7 +1829,7 @@ test( "detach() event cleaning ", 1, function() { test("empty()", function() { - expect( 3 ); + expect( 6 ); equal( jQuery("#ap").children().empty().text().length, 0, "Check text is removed" ); equal( jQuery("#ap").children().length, 4, "Check elements are not removed" ); @@ -1838,7 +1838,13 @@ test("empty()", function() { var j = jQuery("#nonnodes").contents(); j.empty(); equal( j.html(), "", "Check node,textnode,comment empty works" ); -}); + + // Ensure oldIE empties selects (#12336) + notEqual( $("#select1").find("option").length, 0, "Have some initial options" ); + $("#select1").empty(); + equal( $("#select1").find("option").length, 0, "No more option elements found" ); + equal( $("#select1")[0].options.length, 0, "options.length cleared as well" ); + }); test( "jQuery.cleanData", function() { From 4e0bc169df0f6dee45fe7c19925216453b431ebb Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sun, 6 Jan 2013 21:47:02 -0500 Subject: [PATCH 04/80] Fix #12863. Prevent oldIE from calling `.removeAttribute` --- src/manipulation.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manipulation.js b/src/manipulation.js index e8c0fe46f9..3393dd0a56 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -780,7 +780,7 @@ jQuery.extend({ if ( deleteExpando ) { delete elem[ internalKey ]; - } else if ( elem.removeAttribute ) { + } else if ( typeof elem.removeAttribute !== "undefined" ) { elem.removeAttribute( internalKey ); } else { From c27d8e298832b25836dc6ff698cd8400ef207e13 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Tue, 8 Jan 2013 01:16:50 +0000 Subject: [PATCH 05/80] Fix #13103. Add .finish() method. Cherry picked from b6abb31df4d5be80dc13844d9988fb0c990ae5ae. --- src/effects.js | 59 +++++++++++++++++++++++++++++++++++++++++--- src/queue.js | 1 + test/unit/effects.js | 49 ++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 4 deletions(-) diff --git a/src/effects.js b/src/effects.js index 3d9ae7f4ba..7ab3a0869d 100644 --- a/src/effects.js +++ b/src/effects.js @@ -72,6 +72,7 @@ function createTweens( animation, props ) { function Animation( elem, properties, options ) { var result, + stopped, index = 0, length = animationPrefilters.length, deferred = jQuery.Deferred().always( function() { @@ -79,6 +80,9 @@ function Animation( elem, properties, options ) { delete tick.elem; }), tick = function() { + if ( stopped ) { + return false; + } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) @@ -120,7 +124,10 @@ function Animation( elem, properties, options ) { // if we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; - + if ( stopped ) { + return this; + } + stopped = true; for ( ; index < length ; index++ ) { animation.tweens[ index ].run( 1 ); } @@ -477,12 +484,15 @@ jQuery.fn.extend({ doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); - - // Empty animations resolve immediately - if ( empty ) { + doAnimation.finish = function() { + anim.stop( true ); + }; + // Empty animations, or finishing resolves immediately + if ( empty || jQuery._data( this, "finish" ) ) { anim.stop( true ); } }; + doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : @@ -537,6 +547,47 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); } }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = jQuery._data( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // enable finishing flag on private data + data.finish = true; + + // empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.cur && hooks.cur.finish ) { + hooks.cur.finish.call( this ); + } + + // look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // turn off finishing flag + delete data.finish; + }); } }); diff --git a/src/queue.js b/src/queue.js index c5a0cbd7de..d4c3f0040a 100644 --- a/src/queue.js +++ b/src/queue.js @@ -35,6 +35,7 @@ jQuery.extend({ startLength--; } + hooks.cur = fn; if ( fn ) { // Add a progress sentinel to prevent the fx queue from being diff --git a/test/unit/effects.js b/test/unit/effects.js index b615dfd6df..965e9969e5 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1904,4 +1904,53 @@ test( "jQuery.fx.start & jQuery.fx.stop hook points", function() { jQuery.fx.stop = oldStop; }); +test( ".finish() completes all queued animations", function() { + var animations = { + top: 100, + left: 100, + height: 100, + width: 100 + }, + div = jQuery("
"); + + expect( 11 ); + + jQuery.each( animations, function( prop, value ) { + var anim = {}; + anim[ prop ] = value; + // the delay shouldn't matter at all! + div.css( prop, 1 ).animate( anim, function() { + ok( true, "Called animation callback" ); + }).delay( 100 ); + }); + equal( div.queue().length, 8, "8 animations in the queue" ); + div.finish(); + jQuery.each( animations, function( prop, value ) { + equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" ); + }); + equal( div.queue().length, 0, "empty queue when done" ); + equal( div.is(":animated"), false, ":animated doesn't match" ); + + // cleanup + div.remove(); + // leaves a "shadow timer" which does nothing around, need to force a tick + jQuery.fx.tick(); +}); + +test( ".finish() calls finish of custom queue functions", function() { + function queueTester( next ) { + + } + var div = jQuery( "
" ); + + expect( 3 ); + queueTester.finish = function() { + ok( true, "Finish called on custom queue function" ); + }; + + div.queue( queueTester ).queue( queueTester ).queue( queueTester ).finish(); + + div.remove(); +}); + } // if ( jQuery.fx ) From ce67f0ce640854ae6921bed154da772d26a1167e Mon Sep 17 00:00:00 2001 From: Oleg Date: Tue, 8 Jan 2013 01:49:36 +0000 Subject: [PATCH 06/80] Ref #8908. Update IE9 css clone fix. Close gh-1120. --- src/css.js | 4 ++-- src/support.js | 4 ++++ test/unit/css.js | 7 +++++-- test/unit/support.js | 29 +++++++++++++++++++---------- 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/css.js b/src/css.js index 210bed2e80..7ddce0a044 100644 --- a/src/css.js +++ b/src/css.js @@ -213,8 +213,8 @@ jQuery.extend({ // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions - if ( value === "" && name.indexOf("background") === 0 ) { - value = " "; + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value diff --git a/src/support.js b/src/support.js index c99bb39222..4960930efb 100644 --- a/src/support.js +++ b/src/support.js @@ -138,6 +138,10 @@ jQuery.support = (function() { support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; } + div.style.backgroundClip = "content-box"; + div.cloneNode().style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + // Run tests that need a body at doc ready jQuery(function() { var container, marginDiv, tds, diff --git a/test/unit/css.js b/test/unit/css.js index e7ada8bf90..d8f7c01d40 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -923,7 +923,7 @@ test( "css opacity consistency across browsers (#12685)", function() { equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" ); }); -asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", 16, function() { +asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", 24, function() { var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ), styles = [{ name: "backgroundAttachment", @@ -961,7 +961,7 @@ asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Eleme expected: [ "auto auto" ] }]; - jQuery.each( styles, function(index, style) { + jQuery.each(styles, function( index, style ) { var $clone, $clonedChildren, $source = jQuery( "#firstp" ), source = $source[ 0 ], @@ -972,6 +972,7 @@ asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Eleme if ( source.style[ style.name ] === undefined ) { ok( true, style.name + ": style isn't supported and therefore not an issue" ); ok( true ); + ok( true ); return true; } @@ -985,6 +986,8 @@ asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Eleme $clonedChildren.css( style.name, "" ); window.setTimeout(function() { + notEqual( $clone.css( style.name ), style.value[ 0 ], "Cloned css was changed" ); + ok( jQuery.inArray( $source.css( style.name ) !== -1, style.value ), "Clearing clone.css() doesn't affect source.css(): " + style.name + "; result: " + $source.css( style.name ) + diff --git a/test/unit/support.js b/test/unit/support.js index 76a0af7b74..356751d22a 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -81,7 +81,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":true, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } else if ( /opera.*version\/12\.1/i.test( userAgent ) ) { expected = { @@ -114,7 +115,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":true, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } else if ( /msie 10\.0/i.test( userAgent ) ) { expected = { @@ -147,7 +149,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":true, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": false }; } else if ( /msie 9\.0/i.test( userAgent ) ) { expected = { @@ -180,7 +183,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":false, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": false }; } else if ( /msie 8\.0/i.test( userAgent ) ) { expected = { @@ -213,7 +217,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":false, "ajax":true, "cors":false, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } else if ( /msie 7\.0/i.test( userAgent ) ) { expected = { @@ -246,7 +251,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "shrinkWrapBlocks": false, "submitBubbles": false, "tbody": false, - "style": false + "style": false, + "clearCloneStyle": true }; } else if ( /msie 6\.0/i.test( userAgent ) ) { expected = { @@ -279,7 +285,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":false, "ajax":true, "cors":false, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } else if ( /5\.1\.1 safari/i.test( userAgent ) ) { expected = { @@ -312,7 +319,8 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":true, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } else if ( /firefox/i.test( userAgent ) ) { expected = { @@ -345,13 +353,14 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo "reliableHiddenOffsets":true, "ajax":true, "cors":true, - "doesNotIncludeMarginInBodyOffset":true + "doesNotIncludeMarginInBodyOffset":true, + "clearCloneStyle": true }; } if ( expected ) { test("Verify that the support tests resolve as expected per browser", function() { - expect( 30 ); + expect( 31 ); for ( var i in expected ) { if ( jQuery.ajax || i !== "ajax" && i !== "cors" ) { From 0ed497b04595eab5beca1441a134761b11fc9b2f Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Tue, 8 Jan 2013 03:25:26 +0000 Subject: [PATCH 07/80] Resurrect buildFragment and sacrifice jQuery.clean. See gh-1117. --- src/core.js | 3 +-- src/manipulation.js | 48 +++++++++++++++++++-------------------- test/unit/core.js | 9 +++++++- test/unit/manipulation.js | 18 --------------- 4 files changed, 32 insertions(+), 46 deletions(-) diff --git a/src/core.js b/src/core.js index 656fc22f14..8651677578 100644 --- a/src/core.js +++ b/src/core.js @@ -496,8 +496,7 @@ jQuery.extend({ return [ context.createElement( parsed[1] ) ]; } - parsed = context.createDocumentFragment(); - jQuery.clean( [ data ], context, parsed, scripts ); + parsed = jQuery.buildFragment( [ data ], context, scripts ); if ( scripts ) { jQuery( scripts ).remove(); } diff --git a/src/manipulation.js b/src/manipulation.js index 3393dd0a56..416e4c3d64 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -310,8 +310,7 @@ jQuery.fn.extend({ if ( this[0] ) { doc = this[0].ownerDocument; - fragment = doc.createDocumentFragment(); - jQuery.clean( args, doc, fragment, undefined, this ); + fragment = jQuery.buildFragment( args, doc, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { @@ -556,7 +555,7 @@ function getAll( context, tag ) { found; } -// Used in clean, fixes the defaultChecked property +// Used in buildFragment, fixes the defaultChecked property function fixDefaultChecked( elem ) { if ( manipulation_rcheckableType.test( elem.type ) ) { elem.defaultChecked = elem.checked; @@ -619,9 +618,10 @@ jQuery.extend({ return clone; }, - clean: function( elems, context, fragment, scripts, selection ) { + buildFragment: function( elems, context, scripts, selection ) { var elem, i, j, tmp, tag, wrap, tbody, ret = [], + fragment = context.createDocumentFragment(), safe = context === document && safeFragment; // Ensure that context is a document @@ -708,29 +708,27 @@ jQuery.extend({ jQuery.grep( getAll( ret, "input" ), fixDefaultChecked ); } - if ( fragment ) { - for ( i = 0; (elem = ret[i]) != null; i++ ) { - safe = jQuery.contains( elem.ownerDocument, elem ); + for ( i = 0; (elem = ret[i]) != null; i++ ) { + safe = jQuery.contains( elem.ownerDocument, elem ); - // Append to fragment - // #4087 - If origin and destination elements are the same, and this is - // that element, do not append to fragment - if ( !selection || jQuery.inArray( elem, selection ) === -1 ) { - fragment.appendChild( elem ); - } - tmp = getAll( elem, "script" ); + // Append to fragment + // #4087 - If origin and destination elements are the same, and this is + // that element, do not append to fragment + if ( !selection || jQuery.inArray( elem, selection ) === -1 ) { + fragment.appendChild( elem ); + } + tmp = getAll( elem, "script" ); - // Preserve script evaluation history - if ( safe ) { - setGlobalEval( tmp ); - } + // Preserve script evaluation history + if ( safe ) { + setGlobalEval( tmp ); + } - // Capture executables - if ( scripts ) { - for ( j = 0; (elem = tmp[j]) != null; j++ ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } + // Capture executables + if ( scripts ) { + for ( j = 0; (elem = tmp[j]) != null; j++ ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); } } } @@ -738,7 +736,7 @@ jQuery.extend({ elem = tmp = safe = null; - return ret; + return fragment; }, cleanData: function( elems, /* internal */ acceptData ) { diff --git a/test/unit/core.js b/test/unit/core.js index db21c41ccb..f7612896fa 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -1210,7 +1210,7 @@ test("jQuery.proxy", function(){ }); test("jQuery.parseHTML", function() { - expect( 13 ); + expect( 17 ); var html, nodes; @@ -1237,6 +1237,13 @@ test("jQuery.parseHTML", function() { equal( jQuery.parseHTML( "\t
" )[0].nodeValue, "\t", "Preserve leading whitespace" ); equal( jQuery.parseHTML("
")[0].nodeType, 3, "Leading spaces are treated as text nodes (#11290)" ); + + html = jQuery.parseHTML( "
test div
" ); + equal( html[ 0 ].parentNode.nodeType, 11, "parentNode should be documentFragment" ); + equal( html[ 0 ].innerHTML, "test div", "Content should be preserved" ); + + equal( jQuery.parseHTML("").length, 1, "Incorrect html-strings should not break anything" ); + equal( jQuery.parseHTML("")[ 1 ].parentNode.nodeType, 11, "parentNode should be documentFragment" ); }); test("jQuery.parseJSON", function(){ diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index d208b3b7a9..0a110725e4 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -672,24 +672,6 @@ test( "append HTML5 sectioning elements (Bug #6485)", function() { equal( aside.length, 1, "HTML5 elements do not collapse their children" ); }); -test( "jQuery.clean, #12392", function() { - - expect( 6 ); - - var elems = jQuery.clean( [ "
test div
", "

test p

" ] ); - - ok( elems[ 0 ].parentNode == null || elems[ 0 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); - ok( elems[ 1 ].parentNode == null || elems[ 1 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); - - equal( elems[ 0 ].innerHTML, "test div", "Content should be preserved" ); - equal( elems[ 1 ].innerHTML, "test p", "Content should be preserved" ); - - equal( jQuery.clean([ "" ]).length, 1, "Incorrect html-strings should not break anything" ); - - elems = jQuery.clean([ "" ]); - ok( elems[ 1 ].parentNode == null || elems[ 1 ].parentNode.nodeType === 11, "parentNode should be documentFragment or null" ); -}); - if ( jQuery.css ) { test( "HTML5 Elements inherit styles from style rules (Bug #10501)", function() { From 4694118ef79e0800d408b2bc442d0aa2aec1f3eb Mon Sep 17 00:00:00 2001 From: jaubourg Date: Tue, 8 Jan 2013 11:15:36 +0100 Subject: [PATCH 08/80] Opera 12.0 still implements an older version of the DOM so cloneNode cannot be called without an argument --- src/support.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/support.js b/src/support.js index 4960930efb..ce764a1ce0 100644 --- a/src/support.js +++ b/src/support.js @@ -139,7 +139,7 @@ jQuery.support = (function() { } div.style.backgroundClip = "content-box"; - div.cloneNode().style.backgroundClip = ""; + div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; // Run tests that need a body at doc ready From 0c5d2fbabb39ef53a798535bc58690d34ea21351 Mon Sep 17 00:00:00 2001 From: nanto Date: Tue, 8 Jan 2013 16:27:13 +0100 Subject: [PATCH 09/80] Propagate context of returned deferred object in Deferred.then(). Fixes #13160. --- src/deferred.js | 29 +++++++++++++---------------- test/unit/deferred.js | 18 +++++++++++++++++- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/deferred.js b/src/deferred.js index d842065704..0efc05dc3a 100644 --- a/src/deferred.js +++ b/src/deferred.js @@ -21,22 +21,19 @@ jQuery.extend({ return jQuery.Deferred(function( newDefer ) { jQuery.each( tuples, function( i, tuple ) { var action = tuple[ 0 ], - fn = fns[ i ]; + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? - function() { - var returned = fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, [ returned ] ); - } - } : - newDefer[ action ] - ); + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); }); fns = null; }).promise(); @@ -72,7 +69,7 @@ jQuery.extend({ // deferred[ resolve | reject | notify ] deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( promise, arguments ); + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); return this; }; deferred[ tuple[0] + "With" ] = list.fireWith; diff --git a/test/unit/deferred.js b/test/unit/deferred.js index 86b0b34116..f9bc13a9c6 100644 --- a/test/unit/deferred.js +++ b/test/unit/deferred.js @@ -273,7 +273,7 @@ test( "jQuery.Deferred.then - deferred (progress)", function() { test( "jQuery.Deferred.then - context", function() { - expect( 4 ); + expect( 7 ); var context = {}; @@ -284,6 +284,12 @@ test( "jQuery.Deferred.then - context", function() { strictEqual( value, 6, "proper value received" ); }); + jQuery.Deferred().resolve().then(function() { + return jQuery.Deferred().resolveWith(context); + }).done(function() { + strictEqual( this, context, "custom context of returned deferred correctly propagated" ); + }); + var defer = jQuery.Deferred(), piped = defer.then(function( value ) { return value * 3; @@ -295,6 +301,16 @@ test( "jQuery.Deferred.then - context", function() { strictEqual( this, piped, "default context gets updated to latest promise in the chain" ); strictEqual( value, 6, "proper value received" ); }); + + var defer2 = jQuery.Deferred(), + piped2 = defer2.then(); + + defer2.resolve( 2 ); + + piped2.done(function( value ) { + strictEqual( this, piped2, "default context gets updated to latest promise in the chain (without passing function)" ); + strictEqual( value, 2, "proper value received (without passing function)" ); + }); }); test( "jQuery.when", function() { From 11eb1c4e4844650fde794e08d149a09a359e2cda Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Tue, 8 Jan 2013 21:06:04 -0500 Subject: [PATCH 10/80] Tagging the 1.9.0rc1 release. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1fc7d8f46a..af6fc116cd 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.0pre", + "version": "1.9.0rc1", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", @@ -22,7 +22,7 @@ } ], "scripts": { - "test" : "./node_modules/.bin/grunt" + "test": "./node_modules/.bin/grunt" }, "dependencies": {}, "devDependencies": { From a777b355b6c71025124ace023f251f1ffd0a479e Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Tue, 8 Jan 2013 21:06:33 -0500 Subject: [PATCH 11/80] Updating the source version to 1.9.0pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af6fc116cd..a46edffda8 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.0rc1", + "version": "1.9.0pre", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", From 46bbda8d060165bc734e4e84c30b1d62f3ebce27 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 9 Jan 2013 13:23:34 +0400 Subject: [PATCH 12/80] Ref gh-1117: Don't stop on a falsy value in buildFragment. (cherry picked from commit 8e6c1ba92faf830d40cafe7a4deb4ad5ab9045fe) --- src/manipulation.js | 25 +++++++++++++++---------- test/unit/manipulation.js | 3 ++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 416e4c3d64..ce05fd63c4 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -619,8 +619,10 @@ jQuery.extend({ }, buildFragment: function( elems, context, scripts, selection ) { - var elem, i, j, tmp, tag, wrap, tbody, - ret = [], + var elem, j, tmp, tag, wrap, tbody, + nodes = [], + i = 0, + l = elems.length, fragment = context.createDocumentFragment(), safe = context === document && safeFragment; @@ -629,15 +631,16 @@ jQuery.extend({ context = document; } - for ( i = 0; (elem = elems[i]) != null; i++ ) { + for ( ; i < l; i++ ) { + elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( jQuery.type( elem ) === "object" ) { - jQuery.merge( ret, elem.nodeType ? [ elem ] : elem ); + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { - ret.push( context.createTextNode( elem ) ); + nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { @@ -658,7 +661,7 @@ jQuery.extend({ // Manually add leading whitespace removed by IE if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - ret.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); } // Remove IE's autoinserted from table fragments @@ -681,7 +684,7 @@ jQuery.extend({ } } - jQuery.merge( ret, tmp.childNodes ); + jQuery.merge( nodes, tmp.childNodes ); // Fix #12392 for WebKit and IE > 9 tmp.textContent = ""; @@ -705,10 +708,11 @@ jQuery.extend({ // Reset defaultChecked for any radios and checkboxes // about to be appended to the DOM in IE 6/7 (#8060) if ( !jQuery.support.appendChecked ) { - jQuery.grep( getAll( ret, "input" ), fixDefaultChecked ); + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); } - for ( i = 0; (elem = ret[i]) != null; i++ ) { + i = 0; + while ( (elem = nodes[ i++ ]) ) { safe = jQuery.contains( elem.ownerDocument, elem ); // Append to fragment @@ -726,7 +730,8 @@ jQuery.extend({ // Capture executables if ( scripts ) { - for ( j = 0; (elem = tmp[j]) != null; j++ ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 0a110725e4..74e482a47c 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -395,7 +395,7 @@ var testAppendForObject = function( valueObj, isFragment ) { var testAppend = function( valueObj ) { - expect( 59 ); + expect( 60 ); testAppendForObject( valueObj, false ); testAppendForObject( valueObj, true ); @@ -464,6 +464,7 @@ var testAppend = function( valueObj ) { t( "Append Select", "#appendSelect1, #appendSelect2", [ "appendSelect1", "appendSelect2" ] ); equal( "Two nodes", jQuery("
").append( "Two", " nodes" ).text(), "Appending two text nodes (#4011)" ); + equal( jQuery("
").append( "1", "", 3 ).text(), "13", "If median is false-like value, subsequent arguments should not be ignored" ); // using contents will get comments regular, text, and comment nodes j = jQuery("#nonnodes").contents(); From 58003c44ff09cc3142eeddc5bf63f9694d32e3c4 Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Tue, 8 Jan 2013 03:33:01 -0600 Subject: [PATCH 13/80] Adding some more test coverage for .finish() --- test/unit/effects.js | 73 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 72 insertions(+), 1 deletion(-) diff --git a/test/unit/effects.js b/test/unit/effects.js index 965e9969e5..1edecc07a0 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1920,7 +1920,7 @@ test( ".finish() completes all queued animations", function() { anim[ prop ] = value; // the delay shouldn't matter at all! div.css( prop, 1 ).animate( anim, function() { - ok( true, "Called animation callback" ); + ok( true, "Called animation callback for " + prop ); }).delay( 100 ); }); equal( div.queue().length, 8, "8 animations in the queue" ); @@ -1937,6 +1937,77 @@ test( ".finish() completes all queued animations", function() { jQuery.fx.tick(); }); +test( ".finish( false ) - unqueued animations", function() { + var animations = { + top: 100, + left: 100, + height: 100, + width: 100 + }, + div = jQuery("
"); + + expect( 10 ); + + jQuery.each( animations, function( prop, value ) { + var anim = {}; + anim[ prop ] = value; + div.css( prop, 1 ).animate( anim, { + queue: false, + complete: function() { + ok( true, "Called animation callback for " + prop ); + } + }); + }); + equal( div.queue().length, 0, "0 animations in the queue" ); + div.finish( false ); + jQuery.each( animations, function( prop, value ) { + equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" ); + }); + equal( div.is(":animated"), false, ":animated doesn't match" ); + + // cleanup + div.remove(); + // leaves a "shadow timer" which does nothing around, need to force a tick + jQuery.fx.tick(); +}); + +test( ".finish( \"custom\" ) - custom queue animations", function() { + var animations = { + top: 100, + left: 100, + height: 100, + width: 100 + }, + div = jQuery("
"); + + expect( 11 ); + + jQuery.each( animations, function( prop, value ) { + var anim = {}; + anim[ prop ] = value; + div.css( prop, 1 ).animate( anim, { + queue: "custom", + complete: function() { + ok( true, "Called animation callback for " + prop ); + } + }); + }); + equal( div.queue( "custom" ).length, 4, "4 animations in the queue" ); + // start the first animation + div.dequeue( "custom" ); + equal( div.is(":animated"), true, ":animated matches" ); + div.finish( "custom" ); + jQuery.each( animations, function( prop, value ) { + equal( parseFloat( div.css( prop ) ), value, prop + " finished at correct value" ); + }); + equal( div.is(":animated"), false, ":animated doesn't match" ); + + // cleanup + div.remove(); + // leaves a "shadow timer" which does nothing around, need to force a tick + jQuery.fx.tick(); +}); + test( ".finish() calls finish of custom queue functions", function() { function queueTester( next ) { From e348b4060848b46a6c4376661c093e0f0a3ef9e7 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Thu, 10 Jan 2013 10:35:50 -0500 Subject: [PATCH 14/80] Fix map file reference in .min.js file. --- Gruntfile.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index 0c2c8bb93b..11c5c300a1 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -432,11 +432,14 @@ module.exports = function( grunt ) { nonascii = true; } - // Modify map so that it points to files in the same folder; + // Modify map/min so that it points to files in the same folder; // see https://github.com/mishoo/UglifyJS2/issues/47 if ( /\.map$/.test( filename ) ) { text = text.replace( /"dist\//g, "\"" ); fs.writeFileSync( filename, text, "utf-8" ); + } else if ( /\.min\.js$/.test( filename ) ) { + text = text.replace( /sourceMappingURL=dist\//, "sourceMappingURL=" ); + fs.writeFileSync( filename, text, "utf-8" ); } // Optionally copy dist files to other locations From f40eac1d3719be200bea8e62cc73d49fc37b062f Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 10 Jan 2013 15:23:51 -0500 Subject: [PATCH 15/80] Update Sizzle --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index 19c7b34403..693576939a 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 19c7b3440385c9f628a7bc1c5769f6946fcc6887 +Subproject commit 693576939a1ffe62b9266df508f58cda2f901787 From 8b82af9ef25806a3ed8fe7e5bab92ef5f7f13ef7 Mon Sep 17 00:00:00 2001 From: Oleg Date: Wed, 9 Jan 2013 13:52:15 +0400 Subject: [PATCH 16/80] Ref 0ed497b. Close gh-1125. --- src/manipulation.js | 48 +++++++++++++++++++-------------------- test/unit/manipulation.js | 43 ++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index ce05fd63c4..984f80307f 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -33,7 +33,7 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca legend: [ 1, "
" ], area: [ 1, "" ], param: [ 1, "" ], - thead: [ 1, "" ], + thead: [ 1, "
" ], tr: [ 2, "
" ], col: [ 2, "
", "
" ], td: [ 3, "" ], @@ -308,9 +308,8 @@ jQuery.fn.extend({ }); } - if ( this[0] ) { - doc = this[0].ownerDocument; - fragment = jQuery.buildFragment( args, doc, false, this ); + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { @@ -619,21 +618,20 @@ jQuery.extend({ }, buildFragment: function( elems, context, scripts, selection ) { - var elem, j, tmp, tag, wrap, tbody, - nodes = [], - i = 0, + var contains, elem, tag, tmp, wrap, tbody, j, l = elems.length, - fragment = context.createDocumentFragment(), - safe = context === document && safeFragment; - // Ensure that context is a document - if ( !context || typeof context.createDocumentFragment === "undefined" ) { - context = document; - } + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; for ( ; i < l; i++ ) { elem = elems[ i ]; + if ( elem || elem === 0 ) { + // Add nodes directly if ( jQuery.type( elem ) === "object" ) { jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); @@ -644,8 +642,6 @@ jQuery.extend({ // Convert html into DOM nodes } else { - // Ensure a safe container - safe = safe || createSafeFragment( context ); tmp = tmp || safe.appendChild( context.createElement("div") ); // Deserialize a standard representation @@ -700,7 +696,7 @@ jQuery.extend({ } } - // Fix #11356: Clear elements from safeFragment + // Fix #11356: Clear elements from fragment if ( tmp ) { safe.removeChild( tmp ); } @@ -713,18 +709,20 @@ jQuery.extend({ i = 0; while ( (elem = nodes[ i++ ]) ) { - safe = jQuery.contains( elem.ownerDocument, elem ); - // Append to fragment // #4087 - If origin and destination elements are the same, and this is - // that element, do not append to fragment - if ( !selection || jQuery.inArray( elem, selection ) === -1 ) { - fragment.appendChild( elem ); + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; } - tmp = getAll( elem, "script" ); + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); // Preserve script evaluation history - if ( safe ) { + if ( contains ) { setGlobalEval( tmp ); } @@ -739,9 +737,9 @@ jQuery.extend({ } } - elem = tmp = safe = null; + tmp = null; - return fragment; + return safe; }, cleanData: function( elems, /* internal */ acceptData ) { diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 74e482a47c..1d95a73d72 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -395,13 +395,13 @@ var testAppendForObject = function( valueObj, isFragment ) { var testAppend = function( valueObj ) { - expect( 60 ); + expect( 78 ); testAppendForObject( valueObj, false ); testAppendForObject( valueObj, true ); var defaultText, result, message, iframe, iframeDoc, j, d, - $input, $radioChecked, $radioUnchecked, $radioParent; + $input, $radioChecked, $radioUnchecked, $radioParent, $map, $table; defaultText = "Try them out:"; result = jQuery("#first").append( valueObj("buga") ); @@ -446,18 +446,29 @@ var testAppend = function( valueObj ) { jQuery("
").appendTo("#form").append( valueObj("test") ); t( "Append legend", "#legend", [ "legend" ] ); + $map = jQuery("").append( valueObj("jQuery") ); + + equal( $map[ 0 ].childNodes.length, 1, "The area was inserted." ); + equal( $map[ 0 ].firstChild.nodeName.toLowerCase(), "area", "The area was inserted." ); + jQuery("#select1").append( valueObj("") ); equal( jQuery("#select1 option:last").text(), "Test", "Appending OPTION (all caps)" ); - jQuery("#table").append( valueObj("
") ); - equal( jQuery("#table colgroup").length, 1, "Append colgroup" ); + jQuery("#select1").append( valueObj("") ); + equal( jQuery("#select1 optgroup").attr("label"), "optgroup", "Label attribute in newly inserted optgroup is correct" ); + equal( jQuery("#select1 option:last").text(), "optgroup", "Appending optgroup" ); + + $table = jQuery("#table").empty(); + + jQuery.each( "thead tbody tfoot colgroup caption tr th td".split(" "), function( i, name ) { + $table.append( valueObj( "<" + name + "/>" ) ); + ok( $table.find( name ).length >= 1, "Append " + name ); + ok( jQuery.parseHTML( "<" + name + "/>" ).length, name + " wrapped correctly" ); + }); jQuery("#table colgroup").append( valueObj("") ); equal( jQuery("#table colgroup col").length, 1, "Append col" ); - jQuery("#table").append( valueObj("") ); - equal( jQuery("#table caption").length, 1, "Append caption" ); - jQuery("#form") .append( valueObj("") ) .append( valueObj("") ); @@ -2229,9 +2240,19 @@ test( "insertAfter, insertBefore, etc do not work when destination is original e }); test( "Index for function argument should be received (#13094)", 2, function() { - var i = 0; + var i = 0; + + jQuery("
").before(function( index ) { + equal( index, i++, "Index should be correct" ); + }); + +}); + +test( "Make sure jQuery.fn.remove can work on elements in documentFragment", 1, function() { + var fragment = document.createDocumentFragment(), + div = fragment.appendChild( document.createElement("div") ); + + jQuery( div ).remove(); - jQuery("
").before(function( index ) { - equal( index, i++, "Index should be correct" ); - }); + equal( fragment.childNodes.length, 0, "div element was removed from documentFragment" ); }); From 52905676e58989bb6b33b7abb633f7042bab1fd6 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Fri, 11 Jan 2013 12:29:22 -0500 Subject: [PATCH 17/80] Update Sizzle --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index 693576939a..3e40b5d605 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 693576939a1ffe62b9266df508f58cda2f901787 +Subproject commit 3e40b5d6055c192925a28efbd6c4abf5c784508e From 7be47fba08c368c93ec1060d9c5caeb4fe3fd889 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Fri, 11 Jan 2013 16:15:48 -0500 Subject: [PATCH 18/80] Update copyrights used in file headers. --- Gruntfile.js | 2 +- src/intro.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 11c5c300a1..5b45547ff0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -96,7 +96,7 @@ module.exports = function( grunt ) { "dist/jquery.min.js": [ "dist/jquery.js" ] }, options: { - banner: "/*! jQuery v<%= pkg.version %> jquery.com | jquery.org/license */", + banner: "/*! jQuery v<%= pkg.version %> | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */", sourceMap: "dist/jquery.min.map", beautify: { ascii_only: true diff --git a/src/intro.js b/src/intro.js index 0b98012ec6..4e7b69ec35 100644 --- a/src/intro.js +++ b/src/intro.js @@ -5,7 +5,7 @@ * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2012 jQuery Foundation and other contributors + * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * From 9cf812d7a28a08608eab30440102b00ebd3c2291 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sat, 12 Jan 2013 17:11:07 -0500 Subject: [PATCH 19/80] No ticket: compress event.js --- src/effects.js | 4 +- src/event.js | 313 +++++++++++++++++++++++++------------------------ 2 files changed, 164 insertions(+), 153 deletions(-) diff --git a/src/effects.js b/src/effects.js index 7ab3a0869d..f725210247 100644 --- a/src/effects.js +++ b/src/effects.js @@ -161,9 +161,9 @@ function Animation( elem, properties, options ) { jQuery.fx.timer( jQuery.extend( tick, { + elem: elem, anim: animation, - queue: animation.opts.queue, - elem: elem + queue: animation.opts.queue }) ); diff --git a/src/event.js b/src/event.js index adaba76735..5a57fe9f65 100644 --- a/src/event.js +++ b/src/event.js @@ -4,20 +4,31 @@ var rformElems = /^(?:input|select|textarea)$/i, rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { + global: {}, + add: function( elem, types, handler, data, selector ) { - var elemData, eventHandle, events, - tns, type, namespaces, handleObj, - handleObjIn, handlers, special, - t = 0; - // Don't attach events to noData or text/comment nodes (allow plain objects tho) - if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + var handleObjIn, eventHandle, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, + // Don't attach events to noData or text/comment nodes (but allow plain objects) + elemData = elem.nodeType !== 3 && elem.nodeType !== 8 && jQuery._data( elem ); + + if ( !elemData ) { return; } @@ -34,13 +45,11 @@ jQuery.event = { } // Init the element's event structure and main handler, if this is the first - events = elemData.events; - if ( !events ) { - elemData.events = events = {}; + if ( !(events = elemData.events) ) { + events = elemData.events = {}; } - eventHandle = elemData.handle; - if ( !eventHandle ) { - elemData.handle = eventHandle = function( e ) { + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? @@ -54,11 +63,11 @@ jQuery.event = { // Handle multiple events separated by a space // jQuery(...).bind("mouseover mouseout", fn); types = ( types || "" ).match( core_rnotwhite ) || [""]; - for ( ; t < types.length; t++ ) { - - tns = rtypenamespace.exec( types[t] ) || []; - type = tns[1]; - namespaces = ( tns[2] || "" ).split( "." ).sort(); + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; @@ -72,7 +81,7 @@ jQuery.event = { // handleObj is passed to all event handlers handleObj = jQuery.extend({ type: type, - origType: tns[1], + origType: origType, data: data, handler: handler, guid: handler.guid, @@ -82,8 +91,7 @@ jQuery.event = { }, handleObjIn ); // Init the event handler queue if we're the first - handlers = events[ type ]; - if ( !handlers ) { + if ( !(handlers = events[ type ]) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; @@ -122,14 +130,12 @@ jQuery.event = { elem = null; }, - global: {}, - // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { - var tns, type, origType, namespaces, origCount, - j, events, special, eventType, handleObj, - t = 0, + var j, origCount, tmp, + events, t, handleObj, + special, handlers, type, namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { @@ -138,10 +144,11 @@ jQuery.event = { // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( core_rnotwhite ) || [""]; - for ( ; t < types.length; t++ ) { - tns = rtypenamespace.exec( types[t] ) || []; - type = origType = tns[1]; - namespaces = tns[2]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { @@ -152,23 +159,23 @@ jQuery.event = { } special = jQuery.event.special[ type ] || {}; - type = ( selector? special.delegateType : special.bindType ) || type; - eventType = events[ type ] || []; - origCount = eventType.length; - namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); // Remove matching events - for ( j = 0; j < eventType.length; j++ ) { - handleObj = eventType[ j ]; + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && - ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - eventType.splice( j--, 1 ); + handlers.splice( j, 1 ); if ( handleObj.selector ) { - eventType.delegateCount--; + handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); @@ -178,7 +185,7 @@ jQuery.event = { // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) - if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } @@ -199,11 +206,12 @@ jQuery.event = { trigger: function( event, data, elem, onlyHandlers ) { - var i, cur, old, ontype, special, handle, eventPath, bubbleType, + var i, cur, tmp, bubbleType, ontype, handle, special, + eventPath = [ elem || document ], type = event.type || event, namespaces = event.namespace ? event.namespace.split(".") : []; - elem = elem || document; + cur = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { @@ -221,21 +229,19 @@ jQuery.event = { type = namespaces.shift(); namespaces.sort(); } + ontype = type.indexOf(":") < 0 && "on" + type; - // Caller can pass in an Event, Object, or just an event type string - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - new jQuery.Event( type, event ) : - // Just the event type (string) - new jQuery.Event( type ); + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); - event.type = type; event.isTrigger = true; + event.type = type; event.namespace = namespaces.join("."); - event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; - ontype = type.indexOf(":") < 0 ? "on" + type : ""; + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; // Clean up the event in case it is being reused event.result = undefined; @@ -244,8 +250,9 @@ jQuery.event = { } // Clone any incoming data and prepend the event, creating the handler arg list - data = data != null ? jQuery.makeArray( data ) : []; - data.unshift( event ); + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; @@ -255,33 +262,38 @@ jQuery.event = { // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - eventPath = [[ elem, special.bindType || type ]]; if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { bubbleType = special.delegateType || type; - cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; - for ( old = elem; cur; cur = cur.parentNode ) { - eventPath.push([ cur, bubbleType ]); - old = cur; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( old === (elem.ownerDocument || document) ) { - eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path - for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - cur = eventPath[i][0]; - event.type = eventPath[i][1]; + event.type = i > 1 ? + bubbleType : + special.bindType || type; + // jQuery handler handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } - // Note that this is a bare JS function and not a jQuery handler + + // Native handler handle = ontype && cur[ ontype ]; if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { event.preventDefault(); @@ -301,9 +313,9 @@ jQuery.event = { if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method - old = elem[ ontype ]; + tmp = elem[ ontype ]; - if ( old ) { + if ( tmp ) { elem[ ontype ] = null; } @@ -317,8 +329,8 @@ jQuery.event = { } jQuery.event.triggered = undefined; - if ( old ) { - elem[ ontype ] = old; + if ( tmp ) { + elem[ ontype ] = tmp; } } } @@ -333,11 +345,11 @@ jQuery.event = { event = jQuery.event.fix( event ); var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, - handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), - delegateCount = handlers.delegateCount, + handlerQueue = [], args = core_slice.call( arguments ), - special = jQuery.event.special[ event.type ] || {}, - handlerQueue = []; + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + delegateCount = handlers.delegateCount, + special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[0] = event; @@ -358,7 +370,8 @@ jQuery.event = { if ( cur.disabled !== true || event.type !== "click" ) { selMatch = {}; matches = []; - for ( i = 0; i < delegateCount; i++ ) { + i = 0; + for ( ; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; @@ -372,7 +385,7 @@ jQuery.event = { } } if ( matches.length ) { - handlerQueue.push({ elem: cur, matches: matches }); + handlerQueue.push({ elem: cur, handlers: matches }); } } } @@ -380,30 +393,29 @@ jQuery.event = { // Add the remaining (directly-bound) handlers if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); } // Run delegates first; they may want to stop propagation beneath us - for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { - matched = handlerQueue[ i ]; + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; - for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { - handleObj = matched.matches[ j ]; + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { // Triggered event must either 1) have no namespace, or // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - event.data = handleObj.data; event.handleObj = handleObj; + event.data = handleObj.data; ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) .apply( matched.elem, args ); if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { + if ( (event.result = ret) === false ) { event.preventDefault(); event.stopPropagation(); } @@ -420,6 +432,44 @@ jQuery.event = { return event.result; }, + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Safari + // Target should not be a text node (#504) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + // Includes some event props shared by KeyEvent and MouseEvent props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), @@ -470,40 +520,6 @@ jQuery.event = { } }, - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, - originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = jQuery.Event( originalEvent ); - - for ( i = copy.length; i; ) { - prop = copy[ --i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Target should not be a text node (#504, Safari) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) - event.metaKey = !!event.metaKey; - - return fixHook.filter? fixHook.filter( event, originalEvent ) : event; - }, - special: { load: { // Prevent triggered image.load events from bubbling to window.load @@ -512,7 +528,7 @@ jQuery.event = { click: { // For checkbox, fire native event so checked state will be right trigger: function() { - if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { this.click(); return false; } @@ -526,8 +542,9 @@ jQuery.event = { this.focus(); return false; } catch ( e ) { - // IE<9 dies on focus to hidden element (#1486,#12518) - // If this happens, let .trigger() run the handlers + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers } } }, @@ -577,10 +594,6 @@ jQuery.event = { } }; -// Some plugins are using, but it's undocumented/deprecated and will be removed. -// The 1.7 special event interface should provide all the hooks needed now. -jQuery.event.handle = jQuery.event.dispatch; - jQuery.removeEvent = document.removeEventListener ? function( elem, type, handle ) { if ( elem.removeEventListener ) { @@ -635,54 +648,51 @@ jQuery.Event = function( src, props ) { this[ jQuery.expando ] = true; }; -function returnFalse() { - return false; -} -function returnTrue() { - return true; -} - // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { - preventDefault: function() { - this.isDefaultPrevented = returnTrue; + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + preventDefault: function() { var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; if ( !e ) { return; } - // if preventDefault exists run it on the original event + // If preventDefault exists, run it on the original event if ( e.preventDefault ) { e.preventDefault(); - // otherwise set the returnValue property of the original event to false (IE) + // Support: IE + // Otherwise set the returnValue property of the original event to false } else { e.returnValue = false; } }, stopPropagation: function() { - this.isPropagationStopped = returnTrue; - var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; if ( !e ) { return; } - // if stopPropagation exists run it on the original event + // If stopPropagation exists, run it on the original event if ( e.stopPropagation ) { e.stopPropagation(); } - // otherwise set the cancelBubble property of the original event to true (IE) + + // Support: IE + // Set the cancelBubble property of the original event to true e.cancelBubble = true; }, stopImmediatePropagation: function() { this.isImmediatePropagationStopped = returnTrue; this.stopPropagation(); - }, - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse + } }; // Create mouseenter/leave events using mouseover/out and event-time checks @@ -727,11 +737,11 @@ if ( !jQuery.support.submitBubbles ) { // Node name check avoids a VML-related crash in IE (#9807) var elem = e.target, form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !jQuery._data( form, "_submit_attached" ) ) { + if ( form && !jQuery._data( form, "submitBubbles" ) ) { jQuery.event.add( form, "submit._submit", function( event ) { event._submit_bubble = true; }); - jQuery._data( form, "_submit_attached", true ); + jQuery._data( form, "submitBubbles", true ); } }); // return undefined since we don't need an event listener @@ -790,13 +800,13 @@ if ( !jQuery.support.changeBubbles ) { jQuery.event.add( this, "beforeactivate._change", function( e ) { var elem = e.target; - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { jQuery.event.add( elem, "change._change", function( event ) { if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { jQuery.event.simulate( "change", this.parentNode, event, true ); } }); - jQuery._data( elem, "_change_attached", true ); + jQuery._data( elem, "changeBubbles", true ); } }); }, @@ -851,7 +861,7 @@ jQuery.fn.extend({ // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { // && selector != null + if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; @@ -954,8 +964,9 @@ jQuery.fn.extend({ }); }, triggerHandler: function( type, data ) { - if ( this[0] ) { - return jQuery.event.trigger( type, data, this[0], true ); + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); } }, From e5f37953bab7ad53fed7d589ff976f7b72aebc2e Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sat, 12 Jan 2013 19:09:49 -0500 Subject: [PATCH 20/80] Fix 9cf812d7 oldIE failures --- src/event.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index 5a57fe9f65..6c3dc1b80d 100644 --- a/src/event.js +++ b/src/event.js @@ -528,7 +528,7 @@ jQuery.event = { click: { // For checkbox, fire native event so checked state will be right trigger: function() { - if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { this.click(); return false; } From bf4fce70408b67d1bf628932ec31dafa14eb007c Mon Sep 17 00:00:00 2001 From: Oleg Date: Sun, 13 Jan 2013 21:45:52 +0400 Subject: [PATCH 21/80] Fixes #13200 - innerHTML in buildFragment need end tags --- src/manipulation.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 984f80307f..5b462645c2 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -29,18 +29,18 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*\s*$/g, wrapMap = { - option: [ 1, "
" ], - tr: [ 2, "
" ], - col: [ 2, "
", "
" ], - td: [ 3, "" ], + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "
", "
" ], + tr: [ 2, "", "
" ], + col: [ 2, "", "
" ], + td: [ 3, "", "
" ], // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, // unless wrapped in a div with non-breaking characters in front of it. - _default: jQuery.support.htmlSerialize ? [ 0, "" ] : [ 1, "X
" ] + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] }, safeFragment = createSafeFragment( document ), fragmentDiv = safeFragment.appendChild( document.createElement("div") ); @@ -647,7 +647,8 @@ jQuery.extend({ // Deserialize a standard representation tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + ( wrap[2] || "" ); + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; // Descend through wrappers to the right content j = wrap[0]; From 09589c48f179e767fda0bd43a2102ed2a3696cf2 Mon Sep 17 00:00:00 2001 From: Oleg Date: Sun, 13 Jan 2013 23:46:50 +0400 Subject: [PATCH 22/80] Add a comment --- src/manipulation.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/manipulation.js b/src/manipulation.js index 5b462645c2..9f1ecfa7f0 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -28,6 +28,8 @@ var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figca rscriptType = /^$|\/(?:java|ecma)script/i, rscriptTypeMasked = /^true\/(.*)/, rcleanScript = /^\s*\s*$/g, + + // We have to close these tags to support XHTML (#13200) wrapMap = { option: [ 1, "" ], legend: [ 1, "
", "
" ], From 36457cb6afc12d4a755cf93442a502783a669517 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 13:10:40 -0500 Subject: [PATCH 23/80] #13180 unit test --- test/unit/event.js | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/test/unit/event.js b/test/unit/event.js index ff2ea1dd51..182e10b1a3 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1231,17 +1231,21 @@ test(".trigger() doesn't bubble load event (#10717)", function() { jQuery( window ).off( "load" ); }); -test("Delegated events in SVG (#10791)", function() { +test("Delegated events in SVG (#10791; #13180)", function() { expect(2); - var svg = jQuery( + var e, + svg = jQuery( "" + + "" + "" + "" + + "" + "" - ).appendTo( "body" ); + ); - jQuery( "body" ) + jQuery("#qunit-fixture") + .append( svg ) .on( "click", "#svg-by-id", function() { ok( true, "delegated id selector" ); }) @@ -1249,11 +1253,18 @@ test("Delegated events in SVG (#10791)", function() { ok( true, "delegated class selector" ); }) .find( "#svg-by-id, [class~='svg-by-class']" ) - .trigger( "click" ) - .end() - .off( "click" ); + .trigger("click") + .end(); + + // Fire a native click on an SVGElementInstance (the instance tree of an SVG ) + // to confirm that it doesn't break our event delegation handling (#13180) + if ( document.createEvent ) { + e = document.createEvent("MouseEvents"); + e.initEvent( "click", true, true ); + svg.find("#use")[0].instanceRoot.dispatchEvent( e ); + } - svg.remove(); + jQuery("#qunit-fixture").off("click"); }); test("Delegated events in forms (#10844; #11145; #8165; #11382, #11764)", function() { From 14c50da7d55dcc1110277a67fdfc4ede4dffcd91 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 13:11:43 -0500 Subject: [PATCH 24/80] jQuery.event.handlers delegate matching hook point --- src/event.js | 81 +++++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 36 deletions(-) diff --git a/src/event.js b/src/event.js index 6c3dc1b80d..e4bc153f1f 100644 --- a/src/event.js +++ b/src/event.js @@ -344,11 +344,10 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); - var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, + var i, j, ret, matched, handleObj, handlerQueue = [], args = core_slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], - delegateCount = handlers.delegateCount, special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event @@ -361,40 +360,7 @@ jQuery.event = { } // Determine handlers that should run if there are delegated events - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !(event.button && event.type === "click") ) { - - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { - - // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { - selMatch = {}; - matches = []; - i = 0; - for ( ; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - sel = handleObj.selector; - - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( selMatch[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; @@ -432,6 +398,49 @@ jQuery.event = { return event.result; }, + handlers: function( event, handlers ) { + var i, cur, selMatch, matches, handleObj, sel, + handlerQueue = [], + delegateCount = handlers.delegateCount; + + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + i = 0; + for ( ; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + fix: function( event ) { if ( event[ jQuery.expando ] ) { return event; From 7812aab1c966cba860cca302c490cb2e53914400 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 14:01:43 -0500 Subject: [PATCH 25/80] reduce size --- src/event.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/event.js b/src/event.js index e4bc153f1f..f53f67191f 100644 --- a/src/event.js +++ b/src/event.js @@ -359,7 +359,7 @@ jQuery.event = { return; } - // Determine handlers that should run if there are delegated events + // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us @@ -399,30 +399,30 @@ jQuery.event = { }, handlers: function( event, handlers ) { - var i, cur, selMatch, matches, handleObj, sel, + var i, matches, sel, handleObj, handlerQueue = [], - delegateCount = handlers.delegateCount; + delegateCount = handlers.delegateCount, + cur = event.target; + // Find delegate handlers // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && !(event.button && event.type === "click") ) { + if ( delegateCount && (!event.button || event.type !== "click") ) { - for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + for ( ; cur != this; cur = cur.parentNode || this ) { - // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.disabled !== true || event.type !== "click" ) { - selMatch = {}; matches = []; - i = 0; - for ( ; i < delegateCount; i++ ) { + for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; sel = handleObj.selector; - if ( selMatch[ sel ] === undefined ) { - selMatch[ sel ] = handleObj.needsContext ? + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) >= 0 : jQuery.find( sel, this, null, [ cur ] ).length; } - if ( selMatch[ sel ] ) { + if ( matches[ sel ] ) { matches.push( handleObj ); } } @@ -434,7 +434,7 @@ jQuery.event = { } // Add the remaining (directly-bound) handlers - if ( handlers.length > delegateCount ) { + if ( delegateCount < handlers.length ) { handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); } From f860e0bd2f7dd228a14704d78ed5208cbe870d01 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 14:32:38 -0500 Subject: [PATCH 26/80] Fix #13180: don't delegate into SVG --- src/event.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index f53f67191f..2c319f3e07 100644 --- a/src/event.js +++ b/src/event.js @@ -405,8 +405,9 @@ jQuery.event = { cur = event.target; // Find delegate handlers + // Black-hole SVG instance trees (#13180) // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && (!event.button || event.type !== "click") ) { + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { for ( ; cur != this; cur = cur.parentNode || this ) { From a7683d866c87796b1885ea46ec0f7db2e1ef426d Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 20:05:43 -0500 Subject: [PATCH 27/80] No ticket: sync with master @ b75b9ef8 --- src/event.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/event.js b/src/event.js index 2c319f3e07..6c0dc41ca8 100644 --- a/src/event.js +++ b/src/event.js @@ -237,7 +237,6 @@ jQuery.event = { new jQuery.Event( type, typeof event === "object" && event ); event.isTrigger = true; - event.type = type; event.namespace = namespaces.join("."); event.namespace_re = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : @@ -467,8 +466,8 @@ jQuery.event = { event.target = originalEvent.srcElement || document; } - // Support: Safari - // Target should not be a text node (#504) + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) if ( event.target.nodeType === 3 ) { event.target = event.target.parentNode; } From 0a3a424e65f66414305bf6a34fc6fd93d3b61c62 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 20:37:14 -0500 Subject: [PATCH 28/80] Fix f860e0bd Firefox failures --- test/unit/event.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/unit/event.js b/test/unit/event.js index 182e10b1a3..041920a533 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1234,7 +1234,7 @@ test(".trigger() doesn't bubble load event (#10717)", function() { test("Delegated events in SVG (#10791; #13180)", function() { expect(2); - var e, + var instanceRoot, e, svg = jQuery( "" + "" + @@ -1258,10 +1258,11 @@ test("Delegated events in SVG (#10791; #13180)", function() { // Fire a native click on an SVGElementInstance (the instance tree of an SVG ) // to confirm that it doesn't break our event delegation handling (#13180) - if ( document.createEvent ) { + instanceRoot = svg.find("#use")[0].instanceRoot; + if ( instanceRoot && document.createEvent ) { e = document.createEvent("MouseEvents"); e.initEvent( "click", true, true ); - svg.find("#use")[0].instanceRoot.dispatchEvent( e ); + instanceRoot.dispatchEvent( e ); } jQuery("#qunit-fixture").off("click"); From 63f40866fdc9c74c7732084abca040ab06ebabde Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 21:38:40 -0500 Subject: [PATCH 29/80] Fix #13203: delegated events with selector matching Object.prototype property (cherry picked from commit 31b95797155077e4e670c0bbb2c57815f89769a1) --- src/event.js | 4 +++- test/unit/event.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index 6c0dc41ca8..772d65ef49 100644 --- a/src/event.js +++ b/src/event.js @@ -415,7 +415,9 @@ jQuery.event = { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; - sel = handleObj.selector; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; if ( matches[ sel ] === undefined ) { matches[ sel ] = handleObj.needsContext ? diff --git a/test/unit/event.js b/test/unit/event.js index 041920a533..bc98f73cb5 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1797,6 +1797,20 @@ test( "delegated event with delegateTarget-relative selector", function() { markup.remove(); }); +test( "delegated event with selector matching Object.prototype property (#13203)", function() { + expect(1); + + var matched = 0; + + jQuery("#foo").on( "click", "toString", function( e ) { + matched++; + }); + + jQuery("#anchor2").trigger("click"); + + equal( matched, 0, "Nothing matched 'toString'" ); +}); + test("stopPropagation() stops directly-bound events on delegated target", function() { expect(1); From 6c29dd24e9786dfd61cdfdb5d21ffcb5694e25ea Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 13 Jan 2013 22:59:20 -0500 Subject: [PATCH 30/80] 0a3a424e with moar guard for IE6 --- test/unit/event.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/event.js b/test/unit/event.js index bc98f73cb5..6984b4945b 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1234,7 +1234,7 @@ test(".trigger() doesn't bubble load event (#10717)", function() { test("Delegated events in SVG (#10791; #13180)", function() { expect(2); - var instanceRoot, e, + var useElem, e, svg = jQuery( "" + "" + @@ -1258,11 +1258,11 @@ test("Delegated events in SVG (#10791; #13180)", function() { // Fire a native click on an SVGElementInstance (the instance tree of an SVG ) // to confirm that it doesn't break our event delegation handling (#13180) - instanceRoot = svg.find("#use")[0].instanceRoot; - if ( instanceRoot && document.createEvent ) { + useElem = svg.find("#use")[0]; + if ( document.createEvent && useElem && useElem.instanceRoot ) { e = document.createEvent("MouseEvents"); e.initEvent( "click", true, true ); - instanceRoot.dispatchEvent( e ); + useElem.instanceRoot.dispatchEvent( e ); } jQuery("#qunit-fixture").off("click"); From d8b5d5d7c953de4284d37fc45000ca904aa8f2c4 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 14 Jan 2013 21:58:09 -0500 Subject: [PATCH 31/80] Simplify release notes generator script. --- build/release-notes.js | 39 ++++++++++++++++++++++----------------- build/release-notes.txt | 27 --------------------------- 2 files changed, 22 insertions(+), 44 deletions(-) delete mode 100644 build/release-notes.txt diff --git a/build/release-notes.js b/build/release-notes.js index 87710815b0..dff2c11c62 100644 --- a/build/release-notes.js +++ b/build/release-notes.js @@ -5,21 +5,20 @@ var fs = require("fs"), http = require("http"), - tmpl = require("mustache"), - extract = /(.*?)<[^"]+"component">\s*(\S+)/g; + extract = /(.*?)<[^"]+"component">\s*(\S+)/g, + categories = [], + version = process.argv[2]; -var opts = { - version: "1.9 Beta 1", - short_version: "1.9b1", - final_version: "1.9", - categories: [] -}; +if ( !/^\d+\.\d+/.test( version ) ) { + console.error( "Invalid version number: " + version ); + process.exit( 1 ); +} http.request({ host: "bugs.jquery.com", port: 80, method: "GET", - path: "/query?status=closed&resolution=fixed&max=400&component=!web&order=component&milestone=" + opts.final_version + path: "/query?status=closed&resolution=fixed&max=400&component=!web&order=component&milestone=" + version }, function (res) { var data = []; @@ -36,19 +35,25 @@ http.request({ if ( "#" + match[1] !== match[2] ) { var cat = match[3]; - if ( !cur || cur.name !== cat ) { - cur = { name: match[3], niceName: match[3].replace(/^./, function(a){ return a.toUpperCase(); }), bugs: [] }; - opts.categories.push( cur ); + if ( !cur || cur !== cat ) { + if ( cur ) { + console.log(""); + } + cur = cat; + console.log( "

" + cat.charAt(0).toUpperCase() + cat.slice(1) + "

" ); + console.log(""); + } - buildNotes(); }); }).end(); -function buildNotes() { - console.log( tmpl.to_html( fs.readFileSync("release-notes.txt", "utf8"), opts ) ); -} diff --git a/build/release-notes.txt b/build/release-notes.txt deleted file mode 100644 index 1d0ae7460f..0000000000 --- a/build/release-notes.txt +++ /dev/null @@ -1,27 +0,0 @@ -

jQuery {{version}} Released

- -

This is a preview release of jQuery. We're releasing it so that everyone can start testing the code in their applications, making sure that there are no major problems.

- -

You can get the code from the jQuery CDN:

- - - -

You can help us by dropping that code into your existing application and letting us know that if anything no longer works. Please file a bug and be sure to mention that you're testing against jQuery {{version}}.

- -

We want to encourage everyone from the community to try and get involved in contributing back to jQuery core. We've set up a full page of information dedicated towards becoming more involved with the team. The team is here and ready to help you help us!

- -

jQuery {{version}} Change Log

- -

The current change log of the {{version}} release.

- -{{#categories}} -

{{niceName}}

- - -{{/categories}} From 8574d8bd709b7ed1211f60e575cfd97705f077de Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 14 Jan 2013 22:54:13 -0500 Subject: [PATCH 32/80] Tagging the 1.9.0 release. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a46edffda8..a717270fa9 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.0pre", + "version": "1.9.0", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", From 79feac9584396f3628c07d0eed7557d5f70043ec Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 14 Jan 2013 22:54:40 -0500 Subject: [PATCH 33/80] Updating the source version to 1.9.1pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a717270fa9..9e75c2cc2d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.0", + "version": "1.9.1pre", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", From 65df32dc21dc315fe0dcccdcf7d07884f4794ccd Mon Sep 17 00:00:00 2001 From: Mike Sherov Date: Tue, 15 Jan 2013 23:09:35 -0500 Subject: [PATCH 34/80] Fix #13183: Wrong animation initial value calc. Close gh-1136. --- src/css.js | 2 +- src/effects.js | 4 ++-- test/unit/effects.js | 31 ++++++++++++++++++++++++------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/css.js b/src/css.js index 7ddce0a044..03437c2a73 100644 --- a/src/css.js +++ b/src/css.js @@ -265,7 +265,7 @@ jQuery.extend({ } // Return, converting to number if forced or a qualifier was provided and val looks numeric - if ( extra ) { + if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; } diff --git a/src/effects.js b/src/effects.js index f725210247..189f65ce59 100644 --- a/src/effects.js +++ b/src/effects.js @@ -427,11 +427,11 @@ Tween.propHooks = { return tween.elem[ tween.prop ]; } - // passing a non empty string as a 3rd parameter to .css will automatically + // passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails // so, simple values such as "10px" are parsed to Float. // complex values such as "rotate(1rad)" are returned as is. - result = jQuery.css( tween.elem, tween.prop, "auto" ); + result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, diff --git a/test/unit/effects.js b/test/unit/effects.js index 1edecc07a0..aa061058bf 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -283,14 +283,31 @@ test("animate native inline width/height", function() { } }); -test("animate block width/height", function() { - expect(3); +test( "animate block width/height", function() { + expect( 3 ); stop(); - jQuery("#foo").css({ display: "block", width: 20, height: 20 }).animate({ width: 42, height: 42 }, 100, function() { - equal( jQuery(this).css("display"), "block", "inline-block was not set on block element when animating width/height" ); - equal( this.offsetWidth, 42, "width was animated" ); - equal( this.offsetHeight, 42, "height was animated" ); - start(); + + jQuery("
").appendTo("#qunit-fixture").css({ + display: "block", + width: 20, + height: 20, + paddingLeft: 60 + }).animate({ + width: 42, + height: 42 + }, { + duration: 100, + step: function() { + if ( jQuery( this ).width() > 42 ) { + ok( false, "width was incorrectly augmented during animation" ); + } + }, + complete: function() { + equal( jQuery( this ).css("display"), "block", "inline-block was not set on block element when animating width/height" ); + equal( jQuery( this ).width(), 42, "width was animated" ); + equal( jQuery( this ).height(), 42, "height was animated" ); + start(); + } }); }); From fc2ba2e1361126c39f955437ee025cfca3bffa65 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 16 Jan 2013 00:14:57 -0500 Subject: [PATCH 35/80] Fix #13208: only check elements for delegation matches --- src/event.js | 3 ++- test/unit/event.js | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/event.js b/src/event.js index 772d65ef49..6554769ba0 100644 --- a/src/event.js +++ b/src/event.js @@ -410,8 +410,9 @@ jQuery.event = { for ( ; cur != this; cur = cur.parentNode || this ) { + // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.disabled !== true || event.type !== "click" ) { + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { matches = []; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; diff --git a/test/unit/event.js b/test/unit/event.js index 6984b4945b..bde9f7f431 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1811,6 +1811,17 @@ test( "delegated event with selector matching Object.prototype property (#13203) equal( matched, 0, "Nothing matched 'toString'" ); }); +test( "delegated event with intermediate DOM manipulation (#13208)", function() { + expect(1); + + jQuery("#foo").on( "click", "#sap", function() {}); + jQuery("#sap").on( "click", "#anchor2", function() { + jQuery( this.parentNode ).remove(); + ok( true, "Element removed" ); + }); + jQuery("#anchor2").trigger("click"); +}); + test("stopPropagation() stops directly-bound events on delegated target", function() { expect(1); From d8690344b7ba8c0b4a1eb7d57c7c0fcdbbc0ba7c Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 16 Jan 2013 00:16:24 -0500 Subject: [PATCH 36/80] Fix #13182: update Sizzle --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index 3e40b5d605..c04fce3a7e 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 3e40b5d6055c192925a28efbd6c4abf5c784508e +Subproject commit c04fce3a7e3c74ba885a7537e4c39141666cbfe9 From 13468abaeb5488d547bc75d99bc3425ee891859e Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 16 Jan 2013 12:30:47 -0500 Subject: [PATCH 37/80] No ticket: improve replaceWith testing --- test/unit/manipulation.js | 90 +++++++++++++++------------------------ 1 file changed, 35 insertions(+), 55 deletions(-) diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 1d95a73d72..aac966731a 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1148,104 +1148,88 @@ test( "insertAfter(String|Element|Array|jQuery)", function() { var testReplaceWith = function( val ) { - expect( 22 ); + var tmp, y, child, child2, set, non_existent, $div, + expected = 22; - var tmp, y, child, child2, set, non_existant, $div; + expect( expected ); - jQuery("#yahoo").replaceWith(val( "buga" )); - ok( jQuery("#replace")[ 0 ], "Replace element with string" ); + jQuery("#yahoo").replaceWith( val("buga") ); + ok( jQuery("#replace")[ 0 ], "Replace element with element from string" ); ok( !jQuery("#yahoo")[ 0 ], "Verify that original element is gone, after string" ); - QUnit.reset(); - jQuery("#yahoo").replaceWith(val( document.getElementById("first") )); + jQuery("#anchor2").replaceWith( val(document.getElementById("first")) ); ok( jQuery("#first")[ 0 ], "Replace element with element" ); - ok( !jQuery("#yahoo")[ 0 ], "Verify that original element is gone, after element" ); + ok( !jQuery("#anchor2")[ 0 ], "Verify that original element is gone, after element" ); - QUnit.reset(); - jQuery("#qunit-fixture").append("
"); - jQuery("#baz").replaceWith("Baz"); + jQuery("#qunit-fixture").append("
"); + jQuery("#baz").replaceWith( val("Baz") ); equal( jQuery("#bar").text(),"Baz", "Replace element with text" ); ok( !jQuery("#baz")[ 0 ], "Verify that original element is gone, after element" ); - QUnit.reset(); - jQuery("#yahoo").replaceWith( val([ document.getElementById("first"), document.getElementById("mark") ]) ); + jQuery("#google").replaceWith( val([ document.getElementById("first"), document.getElementById("mark") ]) ); ok( jQuery("#first")[ 0 ], "Replace element with array of elements" ); ok( jQuery("#mark")[ 0 ], "Replace element with array of elements" ); - ok( !jQuery("#yahoo")[ 0 ], "Verify that original element is gone, after array of elements" ); + ok( !jQuery("#google")[ 0 ], "Verify that original element is gone, after array of elements" ); - QUnit.reset(); - jQuery("#yahoo").replaceWith( val(jQuery("#mark, #first")) ); + jQuery("#groups").replaceWith( val(jQuery("#mark, #first")) ); ok( jQuery("#first")[ 0 ], "Replace element with set of elements" ); ok( jQuery("#mark")[ 0 ], "Replace element with set of elements" ); - ok( !jQuery("#yahoo")[ 0 ], "Verify that original element is gone, after set of elements" ); + ok( !jQuery("#groups")[ 0 ], "Verify that original element is gone, after set of elements" ); - QUnit.reset(); - tmp = jQuery("
").appendTo("body").click(function() { + + tmp = jQuery("
").appendTo("#qunit-fixture").click(function() { ok( true, "Newly bound click run." ); }); - y = jQuery("
").appendTo("body").click(function() { - ok( true, "Previously bound click run." ); + y = jQuery("
").appendTo("#qunit-fixture").click(function() { + ok( false, "Previously bound click run." ); }); child = y.append("test").find("b").click(function() { ok( true, "Child bound click run." ); return false; }); - y.replaceWith( tmp ); + y.replaceWith( val(tmp) ); tmp.click(); y.click(); // Shouldn't be run child.click(); // Shouldn't be run - tmp.remove(); - y.remove(); - child.remove(); - - QUnit.reset(); - y = jQuery("
").appendTo("body").click(function() { - ok( true, "Previously bound click run." ); + y = jQuery("
").appendTo("#qunit-fixture").click(function() { + ok( false, "Previously bound click run." ); }); child2 = y.append("test").find("u").click(function() { ok( true, "Child 2 bound click run." ); return false; }); - y.replaceWith( child2 ); + y.replaceWith( val(child2) ); child2.click(); - y.remove(); - child2.remove(); - QUnit.reset(); - - set = jQuery("
").replaceWith(val("test")); + set = jQuery("
").replaceWith( val("test") ); equal( set[0].nodeName.toLowerCase(), "div", "No effect on a disconnected node." ); equal( set.length, 1, "No effect on a disconnected node." ); equal( set[0].childNodes.length, 0, "No effect on a disconnected node." ); - non_existant = jQuery("#does-not-exist").replaceWith( val("should not throw an error") ); - equal( non_existant.length, 0, "Length of non existant element." ); - $div = jQuery("
").appendTo("body"); - // TODO: Work on jQuery(...) inline script execution - //$div.replaceWith("
"); - equal(jQuery(".replacewith").length, 1, "Check number of elements in page."); - jQuery(".replacewith").remove(); + non_existent = jQuery("#does-not-exist").replaceWith( val("should not throw an error") ); + equal( non_existent.length, 0, "Length of non existent element." ); - QUnit.reset(); + $div = jQuery("
").appendTo("#qunit-fixture"); + $div.replaceWith( val("
") ); jQuery("#qunit-fixture").append("
"); equal( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); - jQuery("#replaceWith").replaceWith( val("
") ); - equal( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); - + equal( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists after replacement." ); jQuery("#replaceWith").replaceWith( val("
") ); - equal( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists." ); + equal( jQuery("#qunit-fixture").find("div[id=replaceWith]").length, 1, "Make sure only one div exists after subsequent replacement." ); + + return expected; }; test( "replaceWith(String|Element|Array|jQuery)", function() { @@ -1253,17 +1237,13 @@ test( "replaceWith(String|Element|Array|jQuery)", function() { }); test( "replaceWith(Function)", function() { - testReplaceWith( manipulationFunctionReturningObj ); - - expect( 23 ); + expect( testReplaceWith(manipulationFunctionReturningObj) + 1 ); - var y = jQuery("#yahoo")[ 0 ]; + var y = jQuery("#foo")[ 0 ]; - jQuery(y).replaceWith(function() { + jQuery( y ).replaceWith(function() { equal( this, y, "Make sure the context is coming in correctly." ); }); - - QUnit.reset(); }); test( "replaceWith(string) for more than one element", function() { From 6b1b0a26b4d485b4d9f334286efed5dfe33e3f3f Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 16 Jan 2013 12:55:56 -0500 Subject: [PATCH 38/80] Fix #13233: re-allow .replaceWith of text nodes. Close gh-1137. --- src/manipulation.js | 10 ++-------- test/unit/manipulation.js | 6 +++++- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 9f1ecfa7f0..34309d0c94 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -269,15 +269,9 @@ jQuery.fn.extend({ var next = this.nextSibling, parent = this.parentNode; - if ( parent && this.nodeType === 1 || this.nodeType === 11 ) { - + if ( parent ) { jQuery( this ).remove(); - - if ( next ) { - next.parentNode.insertBefore( elem, next ); - } else { - parent.appendChild( elem ); - } + parent.insertBefore( elem, next ); } }); }, diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index aac966731a..3ee260d7e2 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1149,7 +1149,7 @@ test( "insertAfter(String|Element|Array|jQuery)", function() { var testReplaceWith = function( val ) { var tmp, y, child, child2, set, non_existent, $div, - expected = 22; + expected = 23; expect( expected ); @@ -1176,6 +1176,10 @@ var testReplaceWith = function( val ) { ok( jQuery("#mark")[ 0 ], "Replace element with set of elements" ); ok( !jQuery("#groups")[ 0 ], "Verify that original element is gone, after set of elements" ); + tmp = jQuery("content")[0]; + jQuery("#anchor1").contents().replaceWith( val(tmp) ); + deepEqual( jQuery("#anchor1").contents().get(), [ tmp ], "Replace text node with element" ); + tmp = jQuery("
").appendTo("#qunit-fixture").click(function() { ok( true, "Newly bound click run." ); From 8f72967ee2090d4b0d38a59b2e4743e0ce7a1b5e Mon Sep 17 00:00:00 2001 From: danilsomsikov Date: Fri, 11 Jan 2013 16:04:50 +0100 Subject: [PATCH 39/80] Fix #8335: Avoid memory leak by never setting data on non-element non-document nodes. Ref gh-1127. (cherry picked from commit cc324abf739669bd2a4669742c994b86c4ad467b) --- src/data.js | 5 +++++ test/unit/data.js | 13 ++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/data.js b/src/data.js index d5a25ff6c9..eaa483813c 100644 --- a/src/data.js +++ b/src/data.js @@ -223,6 +223,11 @@ jQuery.extend({ // A method for determining if a DOM node can handle the data expando acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; // nodes accept data unless otherwise specified; rejection can be conditional diff --git a/test/unit/data.js b/test/unit/data.js index c09149b65e..8f86d00c4d 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -133,8 +133,16 @@ test("Expando cleanup", 4, function() { jQuery(div).remove(); }); +test("Data is not being set on comment and text nodes", function() { + expect(2); + + ok( !jQuery.hasData( jQuery("").data("foo", 0) ) ); + ok( !jQuery.hasData( jQuery("text").contents().data("foo", 0) ) ); + +}); + test("jQuery.acceptData", function() { - expect(7); + expect(9); ok( jQuery.acceptData( document ), "document" ); ok( jQuery.acceptData( document.documentElement ), "documentElement" ); @@ -149,6 +157,9 @@ test("jQuery.acceptData", function() { var applet = document.createElement("object"); applet.setAttribute("classid", "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"); ok( !jQuery.acceptData( applet ), "applet" ); + + ok( !jQuery.acceptData( document.createComment("") ), "comment" ); + ok( !jQuery.acceptData( document.createTextNode("") ), "text" ); }); test(".data()", function() { From 64bb0c4135aab74fd5958175deec89b18bb2256a Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 16 Jan 2013 14:36:24 -0500 Subject: [PATCH 40/80] Ref 8f72967e: use acceptData to determine when it is safe to add event handlers (cherry picked from commit 50290b8ffb05c504d3866a619f282bf795bc01f6) --- src/event.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/event.js b/src/event.js index 6554769ba0..5841aff7ca 100644 --- a/src/event.js +++ b/src/event.js @@ -25,9 +25,9 @@ jQuery.event = { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, - // Don't attach events to noData or text/comment nodes (but allow plain objects) - elemData = elem.nodeType !== 3 && elem.nodeType !== 8 && jQuery._data( elem ); + elemData = jQuery._data( elem ); + // Don't attach events to noData or text/comment nodes (but allow plain objects) if ( !elemData ) { return; } From 37eb6125c0fb0bec4e0d043bc78110b4f49f3aa6 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 17 Jan 2013 17:00:29 -0500 Subject: [PATCH 41/80] Fix jQuery #13251: use slice instead of substring --- src/data.js | 2 +- src/sizzle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/data.js b/src/data.js index eaa483813c..02cf90ba53 100644 --- a/src/data.js +++ b/src/data.js @@ -253,7 +253,7 @@ jQuery.fn.extend({ name = attrs[i].name; if ( !name.indexOf( "data-" ) ) { - name = jQuery.camelCase( name.substring(5) ); + name = jQuery.camelCase( name.slice(5) ); dataAttr( elem, name, data[ name ] ); } diff --git a/src/sizzle b/src/sizzle index c04fce3a7e..200c872412 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit c04fce3a7e3c74ba885a7537e4c39141666cbfe9 +Subproject commit 200c8724121819f4a6b1f1d155ef9361d0a27518 From c0a370029ed59e6fb5c27f937ba9d2455d9ad714 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Fri, 18 Jan 2013 10:49:10 -0500 Subject: [PATCH 42/80] Update Sizzle: fixes native slice usage --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index 200c872412..3f4445b83e 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 200c8724121819f4a6b1f1d155ef9361d0a27518 +Subproject commit 3f4445b83e731500da91ba477ef0ee0993c41eba From 8b19982144b77e346002c3d1cb690407a841cc18 Mon Sep 17 00:00:00 2001 From: Ryunosuke SATO Date: Mon, 14 Jan 2013 14:45:13 +0900 Subject: [PATCH 43/80] Fix broken link in CONTRIBUTING.md, close gh-1132. --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88a19420a3..6028db34d4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ 2. [Discussion](#discussion) 3. [How To Report Bugs](#how-to-report-bugs) 4. [Core Style Guide](#jquery-core-style-guide) -5. [Tips For Bug Patching](#tips-for-jquery-bug-patching) +5. [Tips For Bug Patching](#tips-for-bug-patching) @@ -12,13 +12,13 @@ There are a number of ways to get involved with the development of jQuery core. Even if you've never contributed code to an Open Source project before, we're always looking for help identifying bugs, writing and reducing test cases and documentation. -This is the best way to contribute to jQuery core. Please read through the full guide detailing [How to Report Bugs](#How-to-Report-Bugs). +This is the best way to contribute to jQuery core. Please read through the full guide detailing [How to Report Bugs](#how-to-report-bugs). ## Discussion ### Forum and IRC -The jQuery core development team frequently tracks posts on the [jQuery Development Forum](http://forum.jquery.com/developing-jquery-core). If you have longer posts or questions please feel free to post them there. If you think you've found a bug please [file it in the bug tracker](#How-to-Report-Bugs). +The jQuery core development team frequently tracks posts on the [jQuery Development Forum](http://forum.jquery.com/developing-jquery-core). If you have longer posts or questions please feel free to post them there. If you think you've found a bug please [file it in the bug tracker](#how-to-report-bugs). Additionally most of the jQuery core development team can be found in the [#jquery-dev](http://webchat.freenode.net/?channels=jquery-dev) IRC channel on irc.freenode.net. From df47eb73f3d3829834137258acbd448a6a9d2440 Mon Sep 17 00:00:00 2001 From: Ryunosuke SATO Date: Mon, 14 Jan 2013 11:59:37 +0900 Subject: [PATCH 44/80] Fix requirements and dependencies in README, close gh-1131. --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6eba3ba522..97b6c220fa 100644 --- a/README.md +++ b/README.md @@ -14,25 +14,23 @@ In the spirit of open source software development, jQuery always encourages comm What you need to build your own jQuery -------------------------------------- -In order to build jQuery, you need to have GNU make 3.8 or later, Node.js/npm latest, and git 1.7 or later. +In order to build jQuery, you need to have Node.js/npm latest and git 1.7 or later. (Earlier versions might work OK, but are not tested.) Windows users have two options: -1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git), - [GNU make for Windows](http://gnuwin32.sourceforge.net/packages/make.htm), and a - [binary version of Node.js](http://node-js.prcn.co.cc/). Make sure all three packages are installed to the same +1. Install [msysgit](https://code.google.com/p/msysgit/) (Full installer for official Git) and a + [binary version of Node.js](http://nodejs.org). Make sure all two packages are installed to the same location (by default, this is C:\Program Files\Git). -2. Install [Cygwin](http://cygwin.com/) (make sure you install the git, make, and which packages), then either follow - the [Node.js build instructions](https://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29) or install - the [binary version of Node.js](http://node-js.prcn.co.cc/). +2. Install [Cygwin](http://cygwin.com/) (make sure you install the git and which packages), and + a [binary version of Node.js](http://nodejs.org/). Mac OS users should install Xcode (comes on your Mac OS install DVD, or downloadable from [Apple's Xcode site](http://developer.apple.com/technologies/xcode.html)) and [Homebrew](http://mxcl.github.com/homebrew/). Once Homebrew is installed, run `brew install git` to install git, and `brew install node` to install Node.js. -Linux/BSD users should use their appropriate package managers to install make, git, and node, or build from source +Linux/BSD users should use their appropriate package managers to install git and Node.js, or build from source if you swing that way. Easy-peasy. From b83081ba644b70876a64b3abd7eb11109c1e7a1d Mon Sep 17 00:00:00 2001 From: jaubourg Date: Mon, 21 Jan 2013 02:44:16 +0100 Subject: [PATCH 45/80] Never use the XML as parsed by the XHR instance. Use raw text instead and let the ajax conversion logic do the trick. -20 min/gzipped. Fixes #13276. Unit test added. --- src/ajax/xhr.js | 9 +-------- test/unit/ajax.js | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 3c1fde374c..2353392f6a 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -105,8 +105,7 @@ if ( xhrSupported ) { var status, statusText, responseHeaders, - responses, - xml; + responses; // Firefox throws exceptions when accessing properties // of an xhr when a network error occurred @@ -136,14 +135,8 @@ if ( xhrSupported ) { } else { responses = {}; status = xhr.status; - xml = xhr.responseXML; responseHeaders = xhr.getAllResponseHeaders(); - // Construct response list - if ( xml && xml.documentElement /* #4958 */ ) { - responses.xml = xml; - } - // When requesting binary data, IE6-9 will throw an exception // on any attempt to access responseText (#11426) if ( typeof xhr.responseText === "string" ) { diff --git a/test/unit/ajax.js b/test/unit/ajax.js index f88b5d7ccb..86d1b19124 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -1483,6 +1483,22 @@ module( "ajax", { }); + ajaxTest( "#13276 - jQuery.ajax() - compatibility between XML documents from ajax requests and parsed string", 1, { + url: "data/dashboard.xml", + dataType: "xml", + success: function( ajaxXML ) { + var parsedXML = jQuery( jQuery.parseXML("blibli") ).find("tab"); + ajaxXML = jQuery( ajaxXML ); + try { + ajaxXML.find("infowindowtab").append( parsedXML ); + } catch( e ) { + strictEqual( e, undefined, "error" ); + return; + } + strictEqual( ajaxXML.find("tab").length, 3, "Parsed node was added properly" ); + } + }); + //----------- jQuery.ajaxPrefilter() ajaxTest( "jQuery.ajaxPrefilter() - abort", 1, { From 3015ee0b5a3cae399b53314bd9a859f61de3b94a Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Mon, 21 Jan 2013 17:06:47 -0500 Subject: [PATCH 46/80] Treat elements as hidden when either offsetWidth OR offsetHeight is 0. Fixes #13132, #10406. --- src/css.js | 2 +- test/unit/css.js | 83 +++++++++++++++++++++++++----------------------- 2 files changed, 44 insertions(+), 41 deletions(-) diff --git a/src/css.js b/src/css.js index 03437c2a73..72b13151b6 100644 --- a/src/css.js +++ b/src/css.js @@ -630,7 +630,7 @@ jQuery(function() { if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.hidden = function( elem ) { - return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); + return elem.offsetWidth === 0 || elem.offsetHeight === 0 || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); }; jQuery.expr.filters.visible = function( elem ) { diff --git a/test/unit/css.js b/test/unit/css.js index d8f7c01d40..101eac0326 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -3,22 +3,14 @@ if ( jQuery.css ) { module("css", { teardown: moduleTeardown }); test("css(String|Hash)", function() { - expect( 46 ); + expect( 41 ); equal( jQuery("#qunit-fixture").css("display"), "block", "Check for css property \"display\"" ); - ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible" ); - jQuery("#nothiddendiv").css({ display: "none" }); - ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden" ); var $child = jQuery("#nothiddendivchild").css({ "width": "20%", "height": "20%" }); notEqual( $child.css("width"), "20px", "Retrieving a width percentage on the child of a hidden div returns percentage" ); notEqual( $child.css("height"), "20px", "Retrieving a height percentage on the child of a hidden div returns percentage" ); - jQuery("#nothiddendiv").css({"display": "block"}); - ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); - ok( jQuery(window).is(":visible"), "Calling is(':visible') on window does not throw an error in IE."); - ok( jQuery(document).is(":visible"), "Calling is(':visible') on document does not throw an error in IE."); - var div = jQuery( "
" ); // These should be "auto" (or some better value) @@ -206,13 +198,7 @@ test("css() explicit and relative values", function() { }); test("css(String, Object)", function() { - expect(22); - - ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible"); - jQuery("#nothiddendiv").css("display", "none"); - ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden"); - jQuery("#nothiddendiv").css("display", "block"); - ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); + expect( 19 ); jQuery("#nothiddendiv").css("top", "-1em"); ok( jQuery("#nothiddendiv").css("top"), -16, "Check negative number in EMs." ); @@ -678,19 +664,6 @@ test("jQuery.css(elem, 'height') doesn't clear radio buttons (bug #1095)", funct ok( ! jQuery(":checkbox:last", $checkedtest).attr("checked"), "Check last checkbox still NOT checked." ); }); -test(":visible selector works properly on table elements (bug #4512)", function () { - expect(1); - - jQuery("#table").html("cellcell"); - equal(jQuery("#table td:visible").length, 1, "hidden cell is not perceived as visible"); -}); - -test(":visible selector works properly on children with a hidden parent (bug #4512)", function () { - expect(1); - jQuery("#table").css("display", "none").html("cellcell"); - equal(jQuery("#table td:visible").length, 0, "hidden cell children not perceived as visible"); -}); - test("internal ref to elem.runtimeStyle (bug #7608)", function () { expect(1); var result = true; @@ -910,17 +883,47 @@ test( "cssHooks - expand", function() { test( "css opacity consistency across browsers (#12685)", function() { expect( 4 ); - var fixture = jQuery("#qunit-fixture"), - style = jQuery("").appendTo(fixture), - el = jQuery("
").appendTo(fixture); - - equal( Math.round( el.css("opacity") * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" ); - el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685"); - equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" ); - el.css( "opacity", 0.3 ); - equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" ); - el.css( "opacity", "" ); - equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" ); + var fixture = jQuery("#qunit-fixture"), + style = jQuery("").appendTo(fixture), + el = jQuery("
").appendTo(fixture); + + equal( Math.round( el.css("opacity") * 100 ), 10, "opacity from style sheet (filter:alpha with spaces)" ); + el.removeClass("opacityWithSpaces_t12685").addClass("opacityNoSpaces_t12685"); + equal( Math.round( el.css("opacity") * 100 ), 20, "opacity from style sheet (filter:alpha without spaces)" ); + el.css( "opacity", 0.3 ); + equal( Math.round( el.css("opacity") * 100 ), 30, "override opacity" ); + el.css( "opacity", "" ); + equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" ); +}); + +test( ":visible/:hidden selectors", function() { + expect( 13 ); + + ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible" ); + jQuery("#nothiddendiv").css({ display: "none" }); + ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden" ); + jQuery("#nothiddendiv").css({"display": "block"}); + ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); + ok( jQuery(window).is(":visible"), "Calling is(':visible') on window does not throw an error in IE."); + ok( jQuery(document).is(":visible"), "Calling is(':visible') on document does not throw an error in IE."); + + ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible"); + jQuery("#nothiddendiv").css("display", "none"); + ok( !jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is hidden"); + jQuery("#nothiddendiv").css("display", "block"); + ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); + + ok( !jQuery("#siblingspan").is(":visible"), "Span with no content not visible (#13132)" ); + var $newDiv = jQuery("
").appendTo("#qunit-fixture"); + equal( $newDiv.find(":visible").length, 0, "Span with no content not visible (#13132)" ); + var $br = jQuery("
").appendTo("#qunit-fixture"); + ok( !$br.is(":visible"), "br element not visible (#10406)"); + + var $table = jQuery("#table"); + $table.html("cellcell"); + equal(jQuery("#table td:visible").length, 1, "hidden cell is not perceived as visible (#4512). Works on table elements"); + $table.css("display", "none").html("cellcell"); + equal(jQuery("#table td:visible").length, 0, "hidden cell children not perceived as visible (#4512)"); }); asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", 24, function() { From bb1d1483451a0be8e16a0169ffccfa719aead1b1 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Mon, 21 Jan 2013 18:12:16 -0500 Subject: [PATCH 47/80] Fix failing tests, add support for empty spans in Opera. Supplements #13132, #10406. --- src/css.js | 5 ++++- test/index.html | 2 +- test/unit/css.js | 6 +++++- test/unit/selector.js | 23 ----------------------- 4 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/css.js b/src/css.js index 72b13151b6..197cc57223 100644 --- a/src/css.js +++ b/src/css.js @@ -630,7 +630,10 @@ jQuery(function() { if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.hidden = function( elem ) { - return elem.offsetWidth === 0 || elem.offsetHeight === 0 || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + return elem.offsetWidth <= 0 || elem.offsetHeight <= 0 || + (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); }; jQuery.expr.filters.visible = function( elem ) { diff --git a/test/index.html b/test/index.html index 45204e27ef..9f8edfe202 100644 --- a/test/index.html +++ b/test/index.html @@ -87,7 +87,7 @@ -
+

See this blog entry for more information.

diff --git a/test/unit/css.js b/test/unit/css.js index 101eac0326..1a3daab846 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -897,7 +897,7 @@ test( "css opacity consistency across browsers (#12685)", function() { }); test( ":visible/:hidden selectors", function() { - expect( 13 ); + expect( 16 ); ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible" ); jQuery("#nothiddendiv").css({ display: "none" }); @@ -924,6 +924,10 @@ test( ":visible/:hidden selectors", function() { equal(jQuery("#table td:visible").length, 1, "hidden cell is not perceived as visible (#4512). Works on table elements"); $table.css("display", "none").html("cellcell"); equal(jQuery("#table td:visible").length, 0, "hidden cell children not perceived as visible (#4512)"); + + t( "Is Visible", "#qunit-fixture div:visible:lt(2)", ["foo", "nothiddendiv"] ); + t( "Is Not Hidden", "#qunit-fixture:hidden", [] ); + t( "Is Hidden", "#form input:hidden", ["hidden1","hidden2"] ); }); asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", 24, function() { diff --git a/test/unit/selector.js b/test/unit/selector.js index 21113207c6..07e563da3a 100644 --- a/test/unit/selector.js +++ b/test/unit/selector.js @@ -63,29 +63,6 @@ test("attributes - jQuery only", function() { ); }); -if ( jQuery.css ) { - test("pseudo - visibility", function() { - expect( 9 ); - - t( "Is Visible", "#qunit-fixture div:visible:lt(2)", ["foo", "nothiddendiv"] ); - t( "Is Not Hidden", "#qunit-fixture:hidden", [] ); - t( "Is Hidden", "#form input:hidden", ["hidden1","hidden2"] ); - - var $div = jQuery("

").appendTo("body"); - $div.css({ fontSize: 0, lineHeight: 0 });// IE also needs to set font-size and line-height to 0 - $div.css( "width", 1 ).css( "height", 0 ); - t( "Is Visible", "#nothiddendivchild:visible", ["nothiddendivchild"] ); - t( "Is Not Visible", "#nothiddendivchild:hidden", [] ); - $div.css( "width", 0 ).css( "height", 1 ); - t( "Is Visible", "#nothiddendivchild:visible", ["nothiddendivchild"] ); - t( "Is Not Visible", "#nothiddendivchild:hidden", [] ); - $div.css( "width", 1 ).css( "height", 1 ); - t( "Is Visible", "#nothiddendivchild:visible", ["nothiddendivchild"] ); - t( "Is Not Visible", "#nothiddendivchild:hidden", [] ); - $div.remove(); - }); -} - test("disconnected nodes", function() { expect( 4 ); var $opt = jQuery("").attr("value", "whipit").appendTo("#qunit-fixture").detach(); From 21af3a9213a2ad0f9996f2ef4f2d8ee53a3f45d4 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Wed, 23 Jan 2013 12:21:48 -0500 Subject: [PATCH 48/80] Ignore file inputs when serializing forms. File input serialization is handled by plugins. Fixes #13306. --- src/serialize.js | 2 +- test/unit/serialize.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/serialize.js b/src/serialize.js index 6e8353d591..65dee4005b 100644 --- a/src/serialize.js +++ b/src/serialize.js @@ -1,7 +1,7 @@ var r20 = /%20/g, rbracket = /\[\]$/, rCRLF = /\r?\n/g, - rsubmitterTypes = /^(?:submit|button|image|reset)$/i, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; jQuery.fn.extend({ diff --git a/test/unit/serialize.js b/test/unit/serialize.js index ab5d1c4271..eff2a00869 100644 --- a/test/unit/serialize.js +++ b/test/unit/serialize.js @@ -112,8 +112,9 @@ test("serialize()", function() { // Add html5 elements only for serialize because selector can't yet find them on non-html5 browsers jQuery("#search").after( - ""+ - "" + "" + + "" + + "" ); equal( jQuery("#form").serialize(), From eb47553eeac58861bcefac063c0e03e161b4d52c Mon Sep 17 00:00:00 2001 From: byroot Date: Thu, 24 Jan 2013 02:33:17 +0100 Subject: [PATCH 49/80] Don't try and convert data for 204 No Content responses. Fixes #13292. Fixes #13261. --- src/ajax.js | 11 ++++++++--- test/data/nocontent.php | 5 +++++ test/unit/ajax.js | 20 ++++++++++++++++++++ 3 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 test/data/nocontent.php diff --git a/src/ajax.js b/src/ajax.js index 6dd34a7326..a7508e9721 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -624,12 +624,17 @@ jQuery.extend({ } } - // If not modified - if ( status === 304 ) { + // if no content + if ( status === 204 ) { + isSuccess = true; + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { isSuccess = true; statusText = "notmodified"; - // If we have data + // If we have data, let's convert it } else { isSuccess = ajaxConvert( s, response ); statusText = isSuccess.state; diff --git a/test/data/nocontent.php b/test/data/nocontent.php new file mode 100644 index 0000000000..9c8431bd7f --- /dev/null +++ b/test/data/nocontent.php @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/test/unit/ajax.js b/test/unit/ajax.js index 86d1b19124..b3734e38b2 100644 --- a/test/unit/ajax.js +++ b/test/unit/ajax.js @@ -1498,6 +1498,26 @@ module( "ajax", { strictEqual( ajaxXML.find("tab").length, 3, "Parsed node was added properly" ); } }); + + ajaxTest( "#13292 - jQuery.ajax() - converter is bypassed for 204 requests", 3, { + url: "data/nocontent.php", + dataType: "testing", + converters: { + "* testing": function() { + throw "converter was called"; + } + }, + success: function( data, status, jqXHR ) { + strictEqual( jqXHR.status, 204, "status code is 204" ); + strictEqual( status, "nocontent", "status text is 'nocontent'" ); + strictEqual( data, undefined, "data is undefined" ); + }, + error: function( _, status, error ) { + ok( false, "error" ); + strictEqual( status, "parsererror", "Parser Error" ); + strictEqual( error, "converter was called", "Converter was called" ); + } + }); //----------- jQuery.ajaxPrefilter() From ec9b38a34fb9bd81d1903cf12b69466f699abca5 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 23 Jan 2013 23:25:29 -0500 Subject: [PATCH 50/80] Fix #13315: compare typeof node.method to var instead of literal "undefined" for safer uglification --- src/attributes.js | 6 +++--- src/core.js | 4 ++++ src/event.js | 4 ++-- src/manipulation.js | 6 +++--- src/offset.js | 2 +- src/support.js | 2 +- 6 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 754a35e879..5aaadb7c4f 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -137,7 +137,7 @@ jQuery.fn.extend({ } // Toggle whole class name - } else if ( type === "undefined" || type === "boolean" ) { + } else if ( type === core_strundefined || type === "boolean" ) { if ( this.className ) { // store className if set jQuery._data( this, "__className__", this.className ); @@ -299,7 +299,7 @@ jQuery.extend({ } // Fallback to prop when attributes are not supported - if ( typeof elem.getAttribute === "undefined" ) { + if ( typeof elem.getAttribute === core_strundefined ) { return jQuery.prop( elem, name, value ); } @@ -332,7 +332,7 @@ jQuery.extend({ // In IE9+, Flash objects don't have .getAttribute (#12945) // Support: IE9+ - if ( typeof elem.getAttribute !== "undefined" ) { + if ( typeof elem.getAttribute !== core_strundefined ) { ret = elem.getAttribute( name ); } diff --git a/src/core.js b/src/core.js index 8651677578..64c9f9cc75 100644 --- a/src/core.js +++ b/src/core.js @@ -5,6 +5,10 @@ var // The deferred used on DOM ready readyList, + // Support: IE<9 + // For `typeof node.method` instead of `node.method !== undefined` + core_strundefined = typeof undefined, + // Use the correct document accordingly with window argument (sandbox) document = window.document, location = window.location, diff --git a/src/event.js b/src/event.js index 5841aff7ca..ca8719b7f4 100644 --- a/src/event.js +++ b/src/event.js @@ -52,7 +52,7 @@ jQuery.event = { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded - return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : undefined; }; @@ -619,7 +619,7 @@ jQuery.removeEvent = document.removeEventListener ? // #8545, #7054, preventing memory leaks for custom events in IE6-8 // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === "undefined" ) { + if ( typeof elem[ name ] === core_strundefined ) { elem[ name ] = null; } diff --git a/src/manipulation.js b/src/manipulation.js index 34309d0c94..569a71d832 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -531,8 +531,8 @@ jQuery.each({ function getAll( context, tag ) { var elems, elem, i = 0, - found = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== "undefined" ? context.querySelectorAll( tag || "*" ) : + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : undefined; if ( !found ) { @@ -778,7 +778,7 @@ jQuery.extend({ if ( deleteExpando ) { delete elem[ internalKey ]; - } else if ( typeof elem.removeAttribute !== "undefined" ) { + } else if ( typeof elem.removeAttribute !== core_strundefined ) { elem.removeAttribute( internalKey ); } else { diff --git a/src/offset.js b/src/offset.js index 04c94cadee..4efb962ff2 100644 --- a/src/offset.js +++ b/src/offset.js @@ -25,7 +25,7 @@ jQuery.fn.offset = function( options ) { // If we don't have gBCR, just use 0,0 rather than error // BlackBerry 5, iOS 3 (original iPhone) - if ( typeof elem.getBoundingClientRect !== "undefined" ) { + if ( typeof elem.getBoundingClientRect !== core_strundefined ) { box = elem.getBoundingClientRect(); } win = getWindow( doc ); diff --git a/src/support.js b/src/support.js index ce764a1ce0..09f894c700 100644 --- a/src/support.js +++ b/src/support.js @@ -201,7 +201,7 @@ jQuery.support = (function() { !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); } - if ( typeof div.style.zoom !== "undefined" ) { + if ( typeof div.style.zoom !== core_strundefined ) { // Support: IE<8 // Check if natively block-level elements act like inline-block // elements when setting their display to 'inline' and giving From 079ee502d6ef150dac0fe8143d55acf93c5a51db Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Thu, 24 Jan 2013 23:10:44 -0500 Subject: [PATCH 51/80] Fix #13281: update Sizzle --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index 3f4445b83e..c0d9badeb5 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit 3f4445b83e731500da91ba477ef0ee0993c41eba +Subproject commit c0d9badeb5dac649d0ba7824efaebbe4155369b5 From ac93559eb9f18fcaec95dfdc97358b1b85bfe234 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Wed, 23 Jan 2013 17:42:28 -0500 Subject: [PATCH 52/80] Fix #13274: Wrap sourceMap directive in multiline comments. Close gh-1143. --- Gruntfile.js | 15 +++++++++++++-- test/data/core/cc_on.html | 22 ++++++++++++++++++++++ test/unit/core.js | 7 +++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 test/data/core/cc_on.html diff --git a/Gruntfile.js b/Gruntfile.js index 5b45547ff0..5ad39bf02d 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -409,7 +409,7 @@ module.exports = function( grunt ) { nonascii = false; distpaths.forEach(function( filename ) { - var i, c, + var i, c, map, text = fs.readFileSync( filename, "utf8" ); // Ensure files use only \n for line endings, not \r\n @@ -438,7 +438,18 @@ module.exports = function( grunt ) { text = text.replace( /"dist\//g, "\"" ); fs.writeFileSync( filename, text, "utf-8" ); } else if ( /\.min\.js$/.test( filename ) ) { - text = text.replace( /sourceMappingURL=dist\//, "sourceMappingURL=" ); + // Wrap sourceMap directive in multiline comments (#13274) + text = text.replace( /\n?(\/\/@\s*sourceMappingURL=)(.*)/, + function( _, directive, path ) { + map = "\n" + directive + path.replace( /^dist\//, "" ); + return ""; + }); + if ( map ) { + text = text.replace( /(^\/\*[\w\W]*?)\s*\*\/|$/, + function( _, comment ) { + return ( comment || "\n/*" ) + map + "\n*/"; + }); + } fs.writeFileSync( filename, text, "utf-8" ); } diff --git a/test/data/core/cc_on.html b/test/data/core/cc_on.html new file mode 100644 index 0000000000..88bb01029a --- /dev/null +++ b/test/data/core/cc_on.html @@ -0,0 +1,22 @@ + + + + + + + + + + + diff --git a/test/unit/core.js b/test/unit/core.js index f7612896fa..373373185d 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -17,6 +17,13 @@ test("Basic requirements", function() { ok( $, "$" ); }); +testIframeWithCallback( "Conditional compilation compatibility (#13274)", "core/cc_on.html", function( cc_on, errors, $ ) { + expect( 3 ); + ok( true, "JScript conditional compilation " + ( cc_on ? "supported" : "not supported" ) ); + deepEqual( errors, [], "No errors" ); + ok( $(), "jQuery executes" ); +}); + test("jQuery()", function() { var elem, i, From a3055f3df63661ad1221db44d04ec92ece130a8c Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sat, 26 Jan 2013 10:48:10 -0500 Subject: [PATCH 53/80] Fix #13316. Use minified version in unit testing. Also migrates the XHR check added to 2.0 in 62acda819f9b6fba9263d0b613e15285807b23a7. --- test/data/ajax/unreleasedXHR.html | 25 +++++++++++++++++++++++ test/data/dimensions/documentLarge.html | 2 +- test/data/dimensions/documentSmall.html | 2 +- test/data/event/promiseReady.html | 2 +- test/data/event/syncReady.html | 2 +- test/data/manipulation/iframe-denied.html | 2 +- test/data/offset/absolute.html | 2 +- test/data/offset/body.html | 2 +- test/data/offset/fixed.html | 2 +- test/data/offset/relative.html | 2 +- test/data/offset/scroll.html | 2 +- test/data/offset/static.html | 2 +- test/data/offset/table.html | 2 +- test/data/selector/html5_selector.html | 2 +- test/data/selector/sizzle_cache.html | 2 +- test/data/support/bodyBackground.html | 2 +- test/data/support/shrinkWrapBlocks.html | 2 +- test/data/support/testElementCrash.html | 2 +- test/delegatetest.html | 2 +- test/hovertest.html | 2 +- test/index.html | 12 +++++------ test/localfile.html | 2 +- test/networkerror.html | 2 +- test/readywait.html | 2 +- 24 files changed, 53 insertions(+), 28 deletions(-) create mode 100644 test/data/ajax/unreleasedXHR.html diff --git a/test/data/ajax/unreleasedXHR.html b/test/data/ajax/unreleasedXHR.html new file mode 100644 index 0000000000..6c3d8210b1 --- /dev/null +++ b/test/data/ajax/unreleasedXHR.html @@ -0,0 +1,25 @@ + + + + +Attempt to block tests because of dangling XHR requests (IE) + + + + + + + diff --git a/test/data/dimensions/documentLarge.html b/test/data/dimensions/documentLarge.html index b2fabd144d..2b5506c10e 100644 --- a/test/data/dimensions/documentLarge.html +++ b/test/data/dimensions/documentLarge.html @@ -11,7 +11,7 @@
- +
diff --git a/test/data/dimensions/documentSmall.html b/test/data/dimensions/documentSmall.html index d5eeacfc2e..12cbf93855 100644 --- a/test/data/dimensions/documentSmall.html +++ b/test/data/dimensions/documentSmall.html @@ -15,7 +15,7 @@
- +
diff --git a/test/data/event/promiseReady.html b/test/data/event/promiseReady.html index 3ea11f05ea..d2b166f322 100644 --- a/test/data/event/promiseReady.html +++ b/test/data/event/promiseReady.html @@ -3,7 +3,7 @@ Test case for jQuery ticket #11470 - + + diff --git a/test/data/manipulation/iframe-denied.html b/test/data/manipulation/iframe-denied.html index da205ff49a..28a5305759 100644 --- a/test/data/manipulation/iframe-denied.html +++ b/test/data/manipulation/iframe-denied.html @@ -6,7 +6,7 @@
- + + + + + + + + + - + diff --git a/test/data/support/bodyBackground.html b/test/data/support/bodyBackground.html index ebfa341c4b..b0abc074fe 100644 --- a/test/data/support/bodyBackground.html +++ b/test/data/support/bodyBackground.html @@ -17,7 +17,7 @@
- +
+
+ + - + + From 74aa3eb79c3329c9f58135f814132d9f99a98fbe Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sat, 26 Jan 2013 13:38:04 -0500 Subject: [PATCH 54/80] Fix build until next grunt rc, disable compare_size. --- Gruntfile.js | 89 +++++++++++++++++++++++++++------------------------- package.json | 7 ++--- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 5ad39bf02d..5826765033 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -22,40 +22,42 @@ module.exports = function( grunt ) { files: distpaths }, selector: { - "src/selector.js": [ - "src/sizzle-jquery.js", - "src/sizzle/sizzle.js" - ] + destFile: "src/selector.js", + apiFile: "src/sizzle-jquery.js", + srcFile: "src/sizzle/sizzle.js" }, build: { - "dist/jquery.js": [ - "src/intro.js", - "src/core.js", - "src/callbacks.js", - "src/deferred.js", - "src/support.js", - "src/data.js", - "src/queue.js", - "src/attributes.js", - "src/event.js", - "src/selector.js", - "src/traversing.js", - "src/manipulation.js", - - { flag: "css", src: "src/css.js" }, - "src/serialize.js", - { flag: "ajax", src: "src/ajax.js" }, - { flag: "ajax/script", src: "src/ajax/script.js", needs: ["ajax"] }, - { flag: "ajax/jsonp", src: "src/ajax/jsonp.js", needs: [ "ajax", "ajax/script" ] }, - { flag: "ajax/xhr", src: "src/ajax/xhr.js", needs: ["ajax"] }, - { flag: "effects", src: "src/effects.js", needs: ["css"] }, - { flag: "offset", src: "src/offset.js", needs: ["css"] }, - { flag: "dimensions", src: "src/dimensions.js", needs: ["css"] }, - { flag: "deprecated", src: "src/deprecated.js" }, - - "src/exports.js", - "src/outro.js" - ] + all:{ + dest: "dist/jquery.js", + src: [ + "src/intro.js", + "src/core.js", + "src/callbacks.js", + "src/deferred.js", + "src/support.js", + "src/data.js", + "src/queue.js", + "src/attributes.js", + "src/event.js", + "src/selector.js", + "src/traversing.js", + "src/manipulation.js", + + { flag: "css", src: "src/css.js" }, + "src/serialize.js", + { flag: "ajax", src: "src/ajax.js" }, + { flag: "ajax/script", src: "src/ajax/script.js", needs: ["ajax"] }, + { flag: "ajax/jsonp", src: "src/ajax/jsonp.js", needs: [ "ajax", "ajax/script" ] }, + { flag: "ajax/xhr", src: "src/ajax/xhr.js", needs: ["ajax"] }, + { flag: "effects", src: "src/effects.js", needs: ["css"] }, + { flag: "offset", src: "src/offset.js", needs: ["css"] }, + { flag: "dimensions", src: "src/dimensions.js", needs: ["css"] }, + { flag: "deprecated", src: "src/deprecated.js" }, + + "src/exports.js", + "src/outro.js" + ] + } }, jshint: { @@ -143,15 +145,15 @@ module.exports = function( grunt ) { }); // Build src/selector.js - grunt.registerMultiTask( "selector", "Build src/selector.js", function() { + grunt.registerTask( "selector", "Build src/selector.js", function() { - var name = this.file.dest, - files = this.file.src, - sizzle = { - api: grunt.file.read( files[0] ), - src: grunt.file.read( files[1] ) - }, - compiled, parts; + var cfg = grunt.config("selector"), + name = cfg.destFile, + sizzle = { + api: grunt.file.read( cfg.apiFile ), + src: grunt.file.read( cfg.srcFile ) + }, + compiled, parts; /** @@ -241,13 +243,14 @@ module.exports = function( grunt ) { "build", "Concatenate source (include/exclude modules with +/- flags), embed date/version", function() { + // Concat specified files. var compiled = "", modules = this.flags, optIn = !modules["*"], explicit = optIn || Object.keys(modules).length > 1, - name = this.file.dest, - src = this.file.srcRaw, + name = this.data.dest, + src = this.data.src, deps = {}, excluded = {}, version = grunt.config( "pkg.version" ), @@ -479,7 +482,7 @@ module.exports = function( grunt ) { grunt.loadNpmTasks("grunt-contrib-uglify"); // Default grunt - grunt.registerTask( "default", [ "update_submodules", "selector", "build:*:*", "jshint", "uglify", "dist:*", "compare_size" ] ); + grunt.registerTask( "default", [ "update_submodules", "selector", "build:*:*", "jshint", "uglify", "dist:*" ] ); // Short list as a high frequency watch task grunt.registerTask( "dev", [ "selector", "build:*:*", "jshint" ] ); diff --git a/package.json b/package.json index 9e75c2cc2d..945e554051 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,9 @@ "grunt-compare-size": "~0.3.0", "grunt-git-authors": "~1.1.0", "grunt-update-submodules": "~0.2.0", - "grunt-contrib-watch": "~0.1.0", - "grunt-contrib-jshint": "~0.1.0", - "grunt-contrib-uglify": "~0.1.0", - "grunt-cli": "~0.1.0", + "grunt-contrib-watch": "~0.1.1", + "grunt-contrib-jshint": "~0.1.1", + "grunt-contrib-uglify": "~0.1.1", "grunt": "~0.4.0", "testswarm": "0.2.2" }, From 3f9f2b1dbcefdafc5ef11f7deb222a3b6d8941d8 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sat, 26 Jan 2013 22:02:15 -0500 Subject: [PATCH 55/80] Fix #12846. Restore overflow when animation is stopped. (Cherry picked from a6c358d) --- src/effects.js | 2 +- test/unit/effects.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/effects.js b/src/effects.js index 189f65ce59..ce7017ef16 100644 --- a/src/effects.js +++ b/src/effects.js @@ -303,7 +303,7 @@ function defaultPrefilter( elem, props, opts ) { if ( opts.overflow ) { style.overflow = "hidden"; if ( !jQuery.support.shrinkWrapBlocks ) { - anim.done(function() { + anim.always(function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; diff --git a/test/unit/effects.js b/test/unit/effects.js index aa061058bf..173af5a0e2 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1787,16 +1787,18 @@ asyncTest("Animation callbacks (#11797)", 15, function() { }); }); -test( "Animate properly sets overflow hidden when animating width/height (#12117)", 4, function() { +test( "Animate properly sets overflow hidden when animating width/height (#12117)", 8, function() { jQuery.each( [ "height", "width" ], function( _, prop ) { jQuery.each( [ 100, 0 ], function( _, value ) { - var div = jQuery("
"), + var div = jQuery("
").css( "overflow", "auto" ), props = {}; props[ prop ] = value; div.animate( props, 1 ); equal( div.css( "overflow" ), "hidden", "overflow: hidden set when animating " + prop + " to " + value ); div.stop(); + equal( div.css( "overflow" ), "auto", + "overflow: auto restored after animating " + prop + " to " + value ); }); }); }); From 24e76245544537e9f085e09d15d3b08efb171b4c Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sat, 26 Jan 2013 23:48:59 -0500 Subject: [PATCH 56/80] Fix #12656. Make event shorthands excludable. --- Gruntfile.js | 1 + src/event-alias.js | 15 +++ src/event.js | 38 ++----- test/unit/attributes.js | 2 +- test/unit/core.js | 9 +- test/unit/event.js | 218 ++++++++++++++++++++------------------ test/unit/manipulation.js | 62 +++++------ 7 files changed, 178 insertions(+), 167 deletions(-) create mode 100644 src/event-alias.js diff --git a/Gruntfile.js b/Gruntfile.js index 5826765033..5d72c24ad9 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -45,6 +45,7 @@ module.exports = function( grunt ) { { flag: "css", src: "src/css.js" }, "src/serialize.js", + { flag: "event-alias", src: "src/event-alias.js" }, { flag: "ajax", src: "src/ajax.js" }, { flag: "ajax/script", src: "src/ajax/script.js", needs: ["ajax"] }, { flag: "ajax/jsonp", src: "src/ajax/jsonp.js", needs: [ "ajax", "ajax/script" ] }, diff --git a/src/event-alias.js b/src/event-alias.js new file mode 100644 index 0000000000..0a87c59655 --- /dev/null +++ b/src/event-alias.js @@ -0,0 +1,15 @@ +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +}); + +jQuery.fn.hover = function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); +}; diff --git a/src/event.js b/src/event.js index ca8719b7f4..7b8b77709f 100644 --- a/src/event.js +++ b/src/event.js @@ -450,10 +450,18 @@ jQuery.event = { } // Create a writable copy of the event object and normalize some properties - var i, prop, + var i, prop, copy, + type = event.type, originalEvent = event, - fixHook = jQuery.event.fixHooks[ event.type ] || {}, - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; event = new jQuery.Event( originalEvent ); @@ -980,29 +988,5 @@ jQuery.fn.extend({ if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } - }, - - hover: function( fnOver, fnOut ) { - return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); - } -}); - -jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + - "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + - "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { - - // Handle event binding - jQuery.fn[ name ] = function( data, fn ) { - return arguments.length > 0 ? - this.on( name, null, data, fn ) : - this.trigger( name ); - }; - - if ( rkeyEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; - } - - if ( rmouseEvent.test( name ) ) { - jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; } }); diff --git a/test/unit/attributes.js b/test/unit/attributes.js index 072240049c..03c3d62ec8 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -316,7 +316,7 @@ test( "attr(String, Object)", function() { equal( $input.attr("checked"), "checked", "Set checked to 'checked' (verified by .attr)" ); var $radios = jQuery("#checkedtest").find("input[type='radio']"); - $radios.eq( 1 ).click(); + $radios.eq( 1 ).trigger("click"); equal( $radios.eq( 1 ).prop("checked"), true, "Second radio was checked when clicked" ); equal( $radios.eq( 0 ).attr("checked"), "checked", "First radio is still [checked]" ); diff --git a/test/unit/core.js b/test/unit/core.js index 373373185d..8a91de4cd5 100644 --- a/test/unit/core.js +++ b/test/unit/core.js @@ -34,9 +34,8 @@ test("jQuery()", function() { div = jQuery("

"), exec = false, lng = "", - expected = 22, + expected = 21, attrObj = { - "click": function() { ok( exec, "Click executed." ); }, "text": "test", "class": "test2", "id": "test3" @@ -44,6 +43,10 @@ test("jQuery()", function() { // The $(html, props) signature can stealth-call any $.fn method, check for a // few here but beware of modular builds where these methods may be excluded. + if ( jQuery.fn.click ) { + expected++; + attrObj["click"] = function() { ok( exec, "Click executed." ); }; + } if ( jQuery.fn.width ) { expected++; attrObj["width"] = 10; @@ -133,7 +136,7 @@ test("jQuery()", function() { equal( elem[0].id, "test3", "jQuery() quick setter id"); exec = true; - elem.click(); + elem.trigger("click"); // manually clean up detached elements elem.remove(); diff --git a/test/unit/event.js b/test/unit/event.js index bde9f7f431..b252a4654e 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -4,12 +4,12 @@ test("null or undefined handler", function() { expect(2); // Supports Fixes bug #7229 try { - jQuery("#firstp").click(null); + jQuery("#firstp").on( "click", null ); ok(true, "Passing a null handler will not throw an exception"); } catch (e) {} try { - jQuery("#firstp").click(undefined); + jQuery("#firstp").on( "click", undefined ); ok(true, "Passing an undefined handler will not throw an exception"); } catch (e) {} }); @@ -66,7 +66,7 @@ test("bind(), with data", function() { ok( event.data, "bind() with data, check passed data exists" ); equal( event.data["foo"], "bar", "bind() with data, Check value of passed data" ); }; - jQuery("#firstp").bind("click", {"foo": "bar"}, handler).click().unbind("click", handler); + jQuery("#firstp").bind("click", {"foo": "bar"}, handler).trigger("click").unbind("click", handler); ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." ); @@ -74,7 +74,7 @@ test("bind(), with data", function() { var handler2 = function(event) { equal( event.data, test, "bind() with function data, Check value of passed data" ); }; - jQuery("#firstp").bind("click", test, handler2).click().unbind("click", handler2); + jQuery("#firstp").bind("click", test, handler2).trigger("click").unbind("click", handler2); }); test("click(), with data", function() { @@ -83,7 +83,7 @@ test("click(), with data", function() { ok( event.data, "bind() with data, check passed data exists" ); equal( event.data["foo"], "bar", "bind() with data, Check value of passed data" ); }; - jQuery("#firstp").click({"foo": "bar"}, handler).click().unbind("click", handler); + jQuery("#firstp").on( "click", {"foo": "bar"}, handler).trigger("click").unbind("click", handler); ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using data." ); }); @@ -391,7 +391,7 @@ test("bind/delegate bubbling, isDefaultPrevented", function() { $jq[0].click(); // IE } }; - $anchor2.click(function(e) { + $anchor2.on( "click", function(e) { e.preventDefault(); }); $main.delegate("#foo", "click", function(e) { @@ -408,7 +408,7 @@ test("bind/delegate bubbling, isDefaultPrevented", function() { fakeClick( $anchor2 ); $anchor2.unbind( "click" ); $main.undelegate( "click" ); - $anchor2.click(function(e) { + $anchor2.on( "click", function(e) { // Let the default action occur }); $main.delegate("#foo", "click", function(e) { @@ -427,7 +427,7 @@ test("bind(), iframes", function() { jQuery("div", doc).bind("click", function() { ok( true, "Binding to element inside iframe" ); - }).click().unbind("click"); + }).trigger("click").unbind("click"); }); test("bind(), trigger change on select", function() { @@ -489,7 +489,7 @@ test("bind(), namespaced events, cloned events", 18, function() { }).trigger("tester"); // Make sure events stick with appendTo'd elements (which are cloned) #2027 - jQuery("test").click(function(){ return false; }).appendTo("#qunit-fixture"); + jQuery("test").on( "click", function(){ return false; }).appendTo("#qunit-fixture"); ok( jQuery("a.test:first").triggerHandler("click") === false, "Handler is bound to appendTo'd elements" ); }); @@ -603,8 +603,8 @@ test("bind(), with different this object", function() { }; jQuery("#firstp") - .bind("click", jQuery.proxy(handler1, thisObject)).click().unbind("click", handler1) - .bind("click", data, jQuery.proxy(handler2, thisObject)).click().unbind("click", handler2); + .bind("click", jQuery.proxy(handler1, thisObject)).trigger("click").unbind("click", handler1) + .bind("click", data, jQuery.proxy(handler2, thisObject)).trigger("click").unbind("click", handler2); ok( !jQuery._data(jQuery("#firstp")[0], "events"), "Event handler unbound when using different this object and data." ); }); @@ -738,7 +738,7 @@ test("unbind(type)", function() { jQuery( document ) .bind( "click", func ) .unbind( "click", func ) - .click() + .trigger("click") .unbind( "click" ); }); @@ -778,33 +778,35 @@ test("unbind(eventObject)", function() { assert( 0 ); }); -test("hover() mouseenter mouseleave", function() { - expect(1); +if ( jQuery.fn.hover ) { + test("hover() mouseenter mouseleave", function() { + expect(1); - var times = 0, - handler1 = function( event ) { ++times; }, - handler2 = function( event ) { ++times; }; + var times = 0, + handler1 = function( event ) { ++times; }, + handler2 = function( event ) { ++times; }; - jQuery("#firstp") - .hover(handler1, handler2) - .mouseenter().mouseleave() - .unbind("mouseenter", handler1) - .unbind("mouseleave", handler2) - .hover(handler1) - .mouseenter().mouseleave() - .unbind("mouseenter mouseleave", handler1) - .mouseenter().mouseleave(); + jQuery("#firstp") + .hover(handler1, handler2) + .mouseenter().mouseleave() + .unbind("mouseenter", handler1) + .unbind("mouseleave", handler2) + .hover(handler1) + .mouseenter().mouseleave() + .unbind("mouseenter mouseleave", handler1) + .mouseenter().mouseleave(); - equal( times, 4, "hover handlers fired" ); + equal( times, 4, "hover handlers fired" ); -}); + }); +} test("mouseover triggers mouseenter", function() { expect(1); var count = 0, elem = jQuery(""); - elem.mouseenter(function () { + elem.on( "mouseenter", function () { count++; }); elem.trigger("mouseover"); @@ -835,65 +837,71 @@ test("withinElement implemented with jQuery.contains()", function() { test("mouseenter, mouseleave don't catch exceptions", function() { expect(2); - var elem = jQuery("#firstp").hover(function() { throw "an Exception"; }); + var elem = jQuery("#firstp").on( "mouseenter mouseleave", function() { + throw "an Exception"; + }); try { - elem.mouseenter(); + elem.trigger("mouseenter"); } catch (e) { equal( e, "an Exception", "mouseenter doesn't catch exceptions" ); } try { - elem.mouseleave(); + elem.trigger("mouseleave"); } catch (e) { equal( e, "an Exception", "mouseleave doesn't catch exceptions" ); } }); -test("trigger() shortcuts", function() { - expect(6); +if ( jQuery.fn.click ) { - var elem = jQuery("
  • Change location
  • ").prependTo("#firstUL"); - elem.find("a").bind("click", function() { - var close = jQuery("spanx", this); // same with jQuery(this).find("span"); - equal( close.length, 0, "Context element does not exist, length must be zero" ); - ok( !close[0], "Context element does not exist, direct access to element must return undefined" ); - return false; - }).click(); + test("trigger() shortcuts", function() { + expect(6); - // manually clean up detached elements - elem.remove(); + var elem = jQuery("
  • Change location
  • ").prependTo("#firstUL"); + elem.find("a").bind("click", function() { + var close = jQuery("spanx", this); // same with jQuery(this).find("span"); + equal( close.length, 0, "Context element does not exist, length must be zero" ); + ok( !close[0], "Context element does not exist, direct access to element must return undefined" ); + return false; + }).click(); - jQuery("#check1").click(function() { - ok( true, "click event handler for checkbox gets fired twice, see #815" ); - }).click(); + // manually clean up detached elements + elem.remove(); - var counter = 0; - jQuery("#firstp")[0].onclick = function(event) { - counter++; - }; - jQuery("#firstp").click(); - equal( counter, 1, "Check that click, triggers onclick event handler also" ); + jQuery("#check1").click(function() { + ok( true, "click event handler for checkbox gets fired twice, see #815" ); + }).click(); - var clickCounter = 0; - jQuery("#simon1")[0].onclick = function(event) { - clickCounter++; - }; - jQuery("#simon1").click(); - equal( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" ); + var counter = 0; + jQuery("#firstp")[0].onclick = function(event) { + counter++; + }; + jQuery("#firstp").click(); + equal( counter, 1, "Check that click, triggers onclick event handler also" ); - elem = jQuery("").load(function(){ - ok( true, "Trigger the load event, using the shortcut .load() (#2819)"); - }).load(); + var clickCounter = 0; + jQuery("#simon1")[0].onclick = function(event) { + clickCounter++; + }; + jQuery("#simon1").click(); + equal( clickCounter, 1, "Check that click, triggers onclick event handler on an a tag also" ); - // manually clean up detached elements - elem.remove(); + elem = jQuery("").load(function(){ + ok( true, "Trigger the load event, using the shortcut .load() (#2819)"); + }).load(); - // test that special handlers do not blow up with VML elements (#7071) - jQuery("").appendTo("head"); - jQuery(" ").appendTo("#form"); - jQuery("#oval").click().keydown(); -}); + // manually clean up detached elements + elem.remove(); + + // test that special handlers do not blow up with VML elements (#7071) + jQuery("").appendTo("head"); + jQuery(" ").appendTo("#form"); + jQuery("#oval").click().keydown(); + }); + +} test("trigger() bubbling", function() { expect(18); @@ -1007,7 +1015,7 @@ test("trigger(type, [data], [fn])", function() { var form = jQuery("
    ").appendTo("body"); // Make sure it can be prevented locally - form.submit(function(){ + form.on( "submit", function(){ ok( true, "Local bind still works." ); return false; }); @@ -1017,7 +1025,7 @@ test("trigger(type, [data], [fn])", function() { form.unbind("submit"); - jQuery(document).submit(function(){ + jQuery(document).on( "submit", function(){ ok( true, "Make sure bubble works up to document." ); return false; }); @@ -1050,7 +1058,7 @@ test( "submit event bubbles on copied forms (#11649)", function() { $fixture.on( "submit", "form", delegatedSubmit ); // Trigger form submission to introduce the _submit_attached property - $testForm.on( "submit", noSubmit ).find("input[name=sub1]").click(); + $testForm.on( "submit", noSubmit ).find("input[name=sub1]").trigger("click"); // Copy the form via .clone() and .html() $formByClone = $testForm.clone( true, true ).removeAttr("id"); @@ -1058,7 +1066,7 @@ test( "submit event bubbles on copied forms (#11649)", function() { $wrapperDiv.append( $formByClone, $formByHTML ); // Check submit bubbling on the copied forms - $wrapperDiv.find("form").on( "submit", noSubmit ).find("input[name=sub1]").click(); + $wrapperDiv.find("form").on( "submit", noSubmit ).find("input[name=sub1]").trigger("click"); // Clean up $wrapperDiv.remove(); @@ -1083,7 +1091,7 @@ test( "change event bubbles on copied forms (#11796)", function(){ $fixture.on( "change", "form", delegatedChange ); // Trigger change event to introduce the _change_attached property - $form.find("select[name=select1]").val("1").change(); + $form.find("select[name=select1]").val("1").trigger("change"); // Copy the form via .clone() and .html() $formByClone = $form.clone( true, true ).removeAttr("id"); @@ -1091,7 +1099,7 @@ test( "change event bubbles on copied forms (#11796)", function(){ $wrapperDiv.append( $formByClone, $formByHTML ); // Check change bubbling on the copied forms - $wrapperDiv.find("form select[name=select1]").val("2").change(); + $wrapperDiv.find("form select[name=select1]").val("2").trigger("change"); // Clean up $wrapperDiv.remove(); @@ -1203,7 +1211,7 @@ test(".trigger() bubbling on disconnected elements (#10489)", function() { .on( "click", function() { ok( true, "click fired on p" ); }) - .click() + .trigger("click") .off( "click" ) .end() .off( "click" ) @@ -1470,7 +1478,7 @@ test("jQuery.Event.currentTarget", function(){ .on( "click", function( e ){ equal( e.currentTarget, this, "Check currentTarget on event" ); }) - .click() + .trigger("click") .off( "click" ) .end() .off( "click" ); @@ -1666,7 +1674,7 @@ test(".delegate()/.undelegate()", function() { jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ jQuery("#nothiddendivchild").html(""); }); jQuery("#body").delegate("#nothiddendivchild", "click", function(e){ if(e.target) {livec++;} }); - jQuery("#nothiddendiv span").click(); + jQuery("#nothiddendiv span").trigger("click"); equal( jQuery("#nothiddendiv span").length, 0, "Verify that first handler occurred and modified the DOM." ); equal( livec, 1, "Verify that second handler occurred even with nuked target." ); @@ -1681,7 +1689,7 @@ test(".delegate()/.undelegate()", function() { jQuery("#body").delegate("span#liveSpan1 a", "click", function(){ lived++; return false; }); jQuery("#body").delegate("span#liveSpan1", "click", function(){ livee++; }); - jQuery("span#liveSpan1 a").click(); + jQuery("span#liveSpan1 a").trigger("click"); equal( lived, 1, "Verify that only one first handler occurred." ); equal( livee, 0, "Verify that second handler doesn't." ); @@ -1691,7 +1699,7 @@ test(".delegate()/.undelegate()", function() { lived = 0; livee = 0; - jQuery("span#liveSpan2 a").click(); + jQuery("span#liveSpan2 a").trigger("click"); equal( lived, 1, "Verify that only one first handler occurred." ); equal( livee, 0, "Verify that second handler doesn't." ); @@ -1706,7 +1714,7 @@ test(".delegate()/.undelegate()", function() { equal( e.target.nodeName.toUpperCase(), "A", "Check the event.target within a delegate handler" ); }); - jQuery("span#liveSpan1 a").click(); + jQuery("span#liveSpan1 a").trigger("click"); jQuery("#body").undelegate("span#liveSpan1", "click"); @@ -1758,7 +1766,7 @@ test("jQuery.off using dispatched jQuery.Event", function() { equal( ++count, 1, "event called once before removal" ); jQuery().off( event ); }) - .find("a").click().click().end() + .find("a").trigger("click").trigger("click").end() .remove(); }); @@ -1776,7 +1784,7 @@ test( "delegated event with delegateTarget-relative selector", function() { ok( this.id === "a0_0" , "first li under #u10 was clicked" ); }) .end() - .find("a").click().end() + .find("a").trigger("click").end() .find("#ul0").off(); // Non-positional selector (#12383) @@ -1792,7 +1800,7 @@ test( "delegated event with delegateTarget-relative selector", function() { .on( "click", "li.test a", function() { ok( true, "li.test is below the delegation point." ); }) - .find("#a0_0").click(); + .find("#a0_0").trigger("click"); markup.remove(); }); @@ -1834,7 +1842,7 @@ test("stopPropagation() stops directly-bound events on delegated target", functi e.stopPropagation(); ok( true, "delegated handler was called" ); }) - .find("a").click().end() + .find("a").trigger("click").end() .remove(); }); @@ -1970,7 +1978,7 @@ test("delegate with submit", function() { ev.preventDefault(); }); - jQuery("#testForm input[name=sub1]").submit(); + jQuery("#testForm input[name=sub1]").trigger("submit"); equal( count1, 1, "Verify form submit." ); equal( count2, 1, "Verify body submit." ); @@ -2015,24 +2023,24 @@ test("inline handler returning false stops default", function() { expect(1); var markup = jQuery(""); - markup.click(function(e) { + markup.on( "click", function(e) { ok( e.isDefaultPrevented(), "inline handler prevented default"); return false; }); - markup.find("a").click(); + markup.find("a").trigger("click"); markup.off("click"); }); test("window resize", function() { expect(2); - jQuery(window).unbind(); + jQuery(window).off(); - jQuery(window).bind("resize", function(){ + jQuery(window).on( "resize", function(){ ok( true, "Resize event fired." ); - }).resize().unbind("resize"); + }).trigger("resize").off("resize"); - ok( !jQuery._data(window, "__events__"), "Make sure all the events are gone." ); + ok( !jQuery._data(window, "events"), "Make sure all the events are gone." ); }); test("focusin bubbles", function() { @@ -2106,7 +2114,7 @@ test(".on and .off", function() { .one( "click", 7, function( e, trig ) { counter += e.data + (trig || 11); // once, 7+11=18 }) - .click() + .trigger("click") .trigger( "click", 17 ) .off( "click" ); equal( counter, 54, "direct event bindings with data" ); @@ -2121,7 +2129,7 @@ test(".on and .off", function() { counter += e.data + (trig || 11); // once, 7+11=18 }) .find("em") - .click() + .trigger("click") .trigger( "click", 17 ) .end() .off( "click", "em" ); @@ -2306,7 +2314,7 @@ test("clone() delegated events (#11076)", function() { .on( "click", "td:last-child", clicked ), clone = table.clone( true ); - clone.find("td").click(); + clone.find("td").trigger("click"); equal( counter["center"], 1, "first child" ); equal( counter["fold"], 1, "last child" ); equal( counter["centerfold"], 2, "all children" ); @@ -2337,7 +2345,7 @@ test("checkbox state (#3827)", function() { // jQuery click cb.checked = true; equal( cb.checked, true, "jQuery - checkbox is initially checked" ); - jQuery( cb ).click(); + jQuery( cb ).trigger("click"); equal( cb.checked, false, "jQuery - checkbox is no longer checked" ); // Handlers only; checkbox state remains false @@ -2348,7 +2356,7 @@ test("focus-blur order (#12868)", function() { expect( 5 ); var $text = jQuery("#text1"), - $radio = jQuery("#radio1").focus(), + $radio = jQuery("#radio1").trigger("focus"), order; // IE6-10 fire focus/blur events asynchronously; this is the resulting mess. @@ -2376,7 +2384,7 @@ test("focus-blur order (#12868)", function() { // Enabled input getting focus order = 0; equal( document.activeElement, $radio[0], "radio has focus" ); - $text.focus(); + $text.trigger("focus"); setTimeout( function() { equal( document.activeElement, $text[0], "text has focus" ); @@ -2612,7 +2620,7 @@ test( "make sure events cloned correctly", 18, function() { ok( true, "Change on original child element is fired" ); }); - fixture.clone().click().change(); // 0 events should be fired + fixture.clone().trigger("click").trigger("change"); // 0 events should be fired clone = fixture.clone( true ); @@ -2628,15 +2636,15 @@ test( "make sure events cloned correctly", 18, function() { p.off(); checkbox.off(); - p.click(); // 0 should be fired - checkbox.change(); // 0 should be fired + p.trigger("click"); // 0 should be fired + checkbox.trigger("change"); // 0 should be fired - clone.find("p:first").trigger( "click", true ); // 3 events should fire + clone.find("p:first").trigger( "click", true ); // 3 events should fire clone.find("#check1").trigger( "change", true ); // 3 events should fire clone.remove(); - clone.find("p:first").click(); // 0 should be fired - clone.find("#check1").change(); // 0 events should fire + clone.find("p:first").trigger("click"); // 0 should be fired + clone.find("#check1").trigger("change"); // 0 events should fire }); test( "Check order of focusin/focusout events", 2, function() { @@ -2657,10 +2665,10 @@ test( "Check order of focusin/focusout events", 2, function() { }); // gain focus - input.focus(); + input.trigger("focus"); // then lose it - jQuery("#search").focus(); + jQuery("#search").trigger("focus"); // cleanup input.off(); diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 3ee260d7e2..73313ea971 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -121,7 +121,7 @@ var testWrap = function( val ) { equal( result.text(), defaultText, "Check for element wrapping" ); QUnit.reset(); - jQuery("#check1").click(function() { + jQuery("#check1").on( "click", function() { var checkbox = this; ok( checkbox.checked, "Checkbox's state is erased after wrap() action, see #769" ); @@ -168,7 +168,7 @@ var testWrap = function( val ) { equal( j[ 0 ].parentNode.nodeName.toLowerCase(), "div", "Wrapping works." ); // Wrap an element with a jQuery set and event - result = jQuery("
    ").click(function() { + result = jQuery("
    ").on( "click", function() { ok( true, "Event triggered." ); // Remove handlers on detached elements @@ -493,7 +493,7 @@ var testAppend = function( valueObj ) { $radioChecked = jQuery("input:radio[name='R1']").eq( 1 ); $radioParent = $radioChecked.parent(); $radioUnchecked = jQuery("").appendTo( $radioParent ); - $radioChecked.click(); + $radioChecked.trigger("click"); $radioUnchecked[ 0 ].checked = false; $radioParent.wrap("
    "); equal( $radioChecked[ 0 ].checked, true, "Reappending radios uphold which radio is checked" ); @@ -641,7 +641,7 @@ test( "append the same fragment with events (Bug #6997, 5566)", function() { // native event handlers on the original object don't get disturbed when they are // modified on the clone if ( doExtra ) { - element = jQuery("div:first").click(function() { + element = jQuery("div:first").on( "click", function() { ok( true, "Event exists on original after being unbound on clone" ); jQuery( this ).unbind("click"); }); @@ -653,20 +653,20 @@ test( "append the same fragment with events (Bug #6997, 5566)", function() { clone.remove(); } - element = jQuery("").click(function() { + element = jQuery("").on( "click", function() { ok( true, "Append second element events work" ); }); jQuery("#listWithTabIndex li").append( element ) - .find("a.test6997").eq( 1 ).click(); + .find("a.test6997").eq( 1 ).trigger("click"); - element = jQuery("
  • ").click(function() { + element = jQuery("
  • ").on( "click", function() { ok( true, "Before second element events work" ); start(); }); jQuery("#listWithTabIndex li").before( element ); - jQuery("#listWithTabIndex li.test6997").eq( 1 ).click(); + jQuery("#listWithTabIndex li.test6997").eq( 1 ).trigger("click"); }); test( "append HTML5 sectioning elements (Bug #6485)", function() { @@ -808,13 +808,13 @@ test( "appendTo(String|Element|Array|jQuery)", function() { t( "Append select", "#foo select", [ "select1" ] ); QUnit.reset(); - div = jQuery("
    ").click(function() { + div = jQuery("
    ").on( "click", function() { ok( true, "Running a cloned click." ); }); div.appendTo("#qunit-fixture, #moretests"); - jQuery("#qunit-fixture div:last").click(); - jQuery("#moretests div:last").click(); + jQuery("#qunit-fixture div:last").trigger("click"); + jQuery("#moretests div:last").trigger("click"); QUnit.reset(); div = jQuery("
    ").appendTo("#qunit-fixture, #moretests"); @@ -1181,35 +1181,35 @@ var testReplaceWith = function( val ) { deepEqual( jQuery("#anchor1").contents().get(), [ tmp ], "Replace text node with element" ); - tmp = jQuery("
    ").appendTo("#qunit-fixture").click(function() { + tmp = jQuery("
    ").appendTo("#qunit-fixture").on( "click", function() { ok( true, "Newly bound click run." ); }); - y = jQuery("
    ").appendTo("#qunit-fixture").click(function() { + y = jQuery("
    ").appendTo("#qunit-fixture").on( "click", function() { ok( false, "Previously bound click run." ); }); - child = y.append("test").find("b").click(function() { + child = y.append("test").find("b").on( "click", function() { ok( true, "Child bound click run." ); return false; }); y.replaceWith( val(tmp) ); - tmp.click(); - y.click(); // Shouldn't be run - child.click(); // Shouldn't be run + tmp.trigger("click"); + y.trigger("click"); // Shouldn't be run + child.trigger("click"); // Shouldn't be run - y = jQuery("
    ").appendTo("#qunit-fixture").click(function() { + y = jQuery("
    ").appendTo("#qunit-fixture").on( "click", function() { ok( false, "Previously bound click run." ); }); - child2 = y.append("test").find("u").click(function() { + child2 = y.append("test").find("u").on( "click", function() { ok( true, "Child 2 bound click run." ); return false; }); y.replaceWith( val(child2) ); - child2.click(); + child2.trigger("click"); set = jQuery("
    ").replaceWith( val("test") ); @@ -1329,7 +1329,7 @@ test( "clone()", function() { equal( jQuery("#nonnodes").contents().clone().length, 3, "Check node,textnode,comment clone works (some browsers delete comments on clone)" ); // Verify that clones of clones can keep event listeners - div = jQuery("
    • test
    ").click(function() { + div = jQuery("
    • test
    ").on( "click", function() { ok( true, "Bound event still exists." ); }); clone = div.clone( true ); div.remove(); @@ -1344,7 +1344,7 @@ test( "clone()", function() { // Verify that cloned children can keep event listeners div = jQuery("
    ").append([ document.createElement("table"), document.createElement("table") ]); - div.find("table").click(function() { + div.find("table").on( "click", function() { ok( true, "Bound event still exists." ); }); @@ -1358,7 +1358,7 @@ test( "clone()", function() { clone.remove(); // Make sure that doing .clone() doesn't clone event listeners - div = jQuery("
    • test
    ").click(function() { + div = jQuery("
    • test
    ").on( "click", function() { ok( false, "Bound event still exists after .clone()." ); }); clone = div.clone(); @@ -1776,9 +1776,9 @@ test( "remove() event cleaning ", 1, function() { count = 0; first = jQuery("#ap").children(":first"); - cleanUp = first.click(function() { + cleanUp = first.on( "click", function() { count++; - }).remove().appendTo("#qunit-fixture").click(); + }).remove().appendTo("#qunit-fixture").trigger("click"); strictEqual( 0, count, "Event handler has been removed" ); @@ -1795,9 +1795,9 @@ test( "detach() event cleaning ", 1, function() { count = 0; first = jQuery("#ap").children(":first"); - cleanUp = first.click(function() { + cleanUp = first.on( "click", function() { count++; - }).detach().appendTo("#qunit-fixture").click(); + }).detach().appendTo("#qunit-fixture").trigger("click"); strictEqual( 1, count, "Event handler has not been removed" ); @@ -1880,13 +1880,13 @@ test( "jQuery.cleanData", function() { div.remove(); function getDiv() { - var div = jQuery("
    ").click(function() { + var div = jQuery("
    ").on( "click", function() { ok( true, type + " " + pos + " Click event fired." ); - }).focus(function() { + }).on( "focus", function() { ok( true, type + " " + pos + " Focus event fired." ); - }).find("div").click(function() { + }).find("div").on( "click", function() { ok( false, type + " " + pos + " Click event fired." ); - }).focus(function() { + }).on( "focus", function() { ok( false, type + " " + pos + " Focus event fired." ); }).end().appendTo("body"); From 5be99ecc48ffb87d4bf7a6a7187a89f359668a35 Mon Sep 17 00:00:00 2001 From: adamcoulombe Date: Thu, 3 Jan 2013 17:05:00 -0500 Subject: [PATCH 57/80] Fix #13150, .has() w/o args checks for any callbacks. Close gh-1111. --- src/callbacks.js | 5 +++-- test/unit/callbacks.js | 47 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/callbacks.js b/src/callbacks.js index 58f1402a84..2bb3780478 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -137,9 +137,10 @@ jQuery.Callbacks = function( options ) { } return this; }, - // Control if a given callback is in the list + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { - return jQuery.inArray( fn, list ) > -1; + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); }, // Remove all callbacks from the list empty: function() { diff --git a/test/unit/callbacks.js b/test/unit/callbacks.js index bd61207ae3..9482832db2 100644 --- a/test/unit/callbacks.js +++ b/test/unit/callbacks.js @@ -269,6 +269,53 @@ test( "jQuery.Callbacks.remove - should remove all instances", function() { }).remove( fn ).fire(); }); +test( "jQuery.Callbacks.has", function() { + + expect( 13 ); + + var cb = jQuery.Callbacks(); + function getA() { + return "A"; + } + function getB() { + return "B"; + } + function getC() { + return "C"; + } + cb.add(getA, getB, getC); + strictEqual( cb.has(), true, "No arguments to .has() returns whether callback function(s) are attached or not" ); + strictEqual( cb.has(getA), true, "Check if a specific callback function is in the Callbacks list" ); + + cb.remove(getB); + strictEqual( cb.has(getB), false, "Remove a specific callback function and make sure its no longer there" ); + strictEqual( cb.has(getA), true, "Remove a specific callback function and make sure other callback function is still there" ); + + cb.empty(); + strictEqual( cb.has(), false, "Empty list and make sure there are no callback function(s)" ); + strictEqual( cb.has(getA), false, "Check for a specific function in an empty() list" ); + + cb.add(getA, getB, function(){ + strictEqual( cb.has(), true, "Check if list has callback function(s) from within a callback function" ); + strictEqual( cb.has(getA), true, "Check if list has a specific callback from within a callback function" ); + }).fire(); + + strictEqual( cb.has(), true, "Callbacks list has callback function(s) after firing" ); + + cb.disable(); + strictEqual( cb.has(), false, "disabled() list has no callback functions (returns false)" ); + strictEqual( cb.has(getA), false, "Check for a specific function in a disabled() list" ); + + cb = jQuery.Callbacks("unique"); + cb.add(getA); + cb.add(getA); + strictEqual( cb.has(), true, "Check if unique list has callback function(s) attached" ); + cb.lock(); + strictEqual( cb.has(), false, "locked() list is empty and returns false" ); + + +}); + test( "jQuery.Callbacks() - adding a string doesn't cause a stack overflow", function() { expect( 1 ); From c4dd702eda2a545a66b8a90ee0291eb46a114f93 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sun, 27 Jan 2013 13:53:47 -0500 Subject: [PATCH 58/80] Update author list. --- AUTHORS.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index 62df6f5a5f..ba8b76e439 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -157,3 +157,6 @@ Yiming He Devin Cooper Bennett Sorbo Sebastian Burkhard +Danil Somsikov +Jean Boussier +Adam Coulombe From 1bbe2b1ded24edf7bf7b18512aff4148591803da Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Tue, 29 Jan 2013 20:57:26 -0500 Subject: [PATCH 59/80] Fix #13349. No need to sort simple .find() cases. --- src/traversing.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/traversing.js b/src/traversing.js index 99c3810100..8d8b9930f7 100644 --- a/src/traversing.js +++ b/src/traversing.js @@ -12,12 +12,13 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var i, ret, self; + var i, ret, self, + len = this.length; if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < self.length; i++ ) { + for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } @@ -26,12 +27,12 @@ jQuery.fn.extend({ } ret = []; - for ( i = 0; i < this.length; i++ ) { + for ( i = 0; i < len; i++ ) { jQuery.find( selector, this[ i ], ret ); } // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( jQuery.unique( ret ) ); + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); ret.selector = ( this.selector ? this.selector + " " : "" ) + selector; return ret; }, From 1e1ea2c44fdca57c64a02aedee57b9bd0582e34c Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Wed, 30 Jan 2013 20:09:56 -0500 Subject: [PATCH 60/80] Revert change to visible/hidden selectors until 1.10 and 2.1. Reopens #13132, #10406. --- src/css.js | 2 +- test/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/css.js b/src/css.js index 197cc57223..57d61925ec 100644 --- a/src/css.js +++ b/src/css.js @@ -632,7 +632,7 @@ if ( jQuery.expr && jQuery.expr.filters ) { jQuery.expr.filters.hidden = function( elem ) { // Support: Opera <= 12.12 // Opera reports offsetWidths and offsetHeights less than zero on some elements - return elem.offsetWidth <= 0 || elem.offsetHeight <= 0 || + return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); }; diff --git a/test/index.html b/test/index.html index cedbb82821..918d7d2d70 100644 --- a/test/index.html +++ b/test/index.html @@ -87,7 +87,7 @@ -
    +

    See this blog entry for more information.

    From 2a707740360964caf27f85395544f7131193bcc8 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Wed, 30 Jan 2013 20:40:39 -0500 Subject: [PATCH 61/80] Minor updates. All parameters of an internal function are for internal use only. --- src/data.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/data.js b/src/data.js index 02cf90ba53..95aa0dc307 100644 --- a/src/data.js +++ b/src/data.js @@ -1,7 +1,7 @@ var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; - -function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + +function internalData( elem, name, data, pvt ) { if ( !jQuery.acceptData( elem ) ) { return; } @@ -95,7 +95,7 @@ function internalData( elem, name, data, pvt /* Internal Use Only */ ){ return ret; } -function internalRemoveData( elem, name, pvt /* For internal use only */ ){ +function internalRemoveData( elem, name, pvt ) { if ( !jQuery.acceptData( elem ) ) { return; } @@ -205,11 +205,11 @@ jQuery.extend({ }, data: function( elem, name, data ) { - return internalData( elem, name, data, false ); + return internalData( elem, name, data ); }, removeData: function( elem, name ) { - return internalRemoveData( elem, name, false ); + return internalRemoveData( elem, name ); }, // For internal use only. @@ -304,12 +304,12 @@ function dataAttr( elem, key, data ) { if ( typeof data === "string" ) { try { data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; } catch( e ) {} // Make sure we set the data so it isn't changed later From dc931af877d59806dbbb826036ab9b23bdbabd32 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Wed, 30 Jan 2013 20:52:06 -0500 Subject: [PATCH 62/80] Again, magic fixing for previous commit. --- test/unit/css.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/unit/css.js b/test/unit/css.js index 1a3daab846..f7c7ad424d 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -897,7 +897,7 @@ test( "css opacity consistency across browsers (#12685)", function() { }); test( ":visible/:hidden selectors", function() { - expect( 16 ); + expect( 13 ); ok( jQuery("#nothiddendiv").is(":visible"), "Modifying CSS display: Assert element is visible" ); jQuery("#nothiddendiv").css({ display: "none" }); @@ -913,11 +913,11 @@ test( ":visible/:hidden selectors", function() { jQuery("#nothiddendiv").css("display", "block"); ok( jQuery("#nothiddendiv").is(":visible"), "Modified CSS display: Assert element is visible"); - ok( !jQuery("#siblingspan").is(":visible"), "Span with no content not visible (#13132)" ); - var $newDiv = jQuery("

    ").appendTo("#qunit-fixture"); - equal( $newDiv.find(":visible").length, 0, "Span with no content not visible (#13132)" ); - var $br = jQuery("
    ").appendTo("#qunit-fixture"); - ok( !$br.is(":visible"), "br element not visible (#10406)"); + // ok( !jQuery("#siblingspan").is(":visible"), "Span with no content not visible (#13132)" ); + // var $newDiv = jQuery("
    ").appendTo("#qunit-fixture"); + // equal( $newDiv.find(":visible").length, 0, "Span with no content not visible (#13132)" ); + // var $br = jQuery("
    ").appendTo("#qunit-fixture"); + // ok( !$br.is(":visible"), "br element not visible (#10406)"); var $table = jQuery("#table"); $table.html("cellcell"); From e392e5579b9f8f1e20c0befe0577e5141fc45468 Mon Sep 17 00:00:00 2001 From: Oleg Date: Fri, 25 Jan 2013 06:26:16 +0400 Subject: [PATCH 63/80] Change variables initialization sequence for some declarations --- src/attributes.js | 2 +- src/callbacks.js | 10 +++++----- src/core.js | 6 +++--- src/event.js | 16 ++++++++-------- src/manipulation.js | 8 ++++---- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 5aaadb7c4f..7d4fd94922 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -166,7 +166,7 @@ jQuery.fn.extend({ }, val: function( value ) { - var hooks, ret, isFunction, + var ret, hooks, isFunction, elem = this[0]; if ( !arguments.length ) { diff --git a/src/callbacks.js b/src/callbacks.js index 2bb3780478..32c22ce59c 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -40,18 +40,18 @@ jQuery.Callbacks = function( options ) { ( optionsCache[ options ] || createOptions( options ) ) : jQuery.extend( {}, options ); - var // Last fire value (for non-forgettable lists) + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) memory, // Flag to know if list was already fired fired, - // Flag to know if list is currently firing - firing, // First callback to fire (used internally by add and fireWith) firingStart, - // End of the loop when firing - firingLength, // Index of currently firing callback (modified by remove if needed) firingIndex, + // End of the loop when firing + firingLength, // Actual callback list list = [], // Stack of fire calls for repeatable lists diff --git a/src/core.js b/src/core.js index 64c9f9cc75..4098f8fef1 100644 --- a/src/core.js +++ b/src/core.js @@ -93,7 +93,7 @@ jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { - var match, elem; + var elem, match; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { @@ -288,7 +288,7 @@ jQuery.fn = jQuery.prototype = { jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { - var options, name, src, copy, copyIsArray, clone, + var copy, options, src, copyIsArray, name, clone, target = arguments[0] || {}, i = 1, length = arguments.length, @@ -770,7 +770,7 @@ jQuery.extend({ // Bind a function to a context, optionally partially applying any // arguments. proxy: function( fn, context ) { - var tmp, args, proxy; + var args, proxy, tmp; if ( typeof context === "string" ) { tmp = fn[ context ]; diff --git a/src/event.js b/src/event.js index 7b8b77709f..c10c684df4 100644 --- a/src/event.js +++ b/src/event.js @@ -22,9 +22,9 @@ jQuery.event = { add: function( elem, types, handler, data, selector ) { - var handleObjIn, eventHandle, tmp, - events, t, handleObj, - special, handlers, type, namespaces, origType, + var handleObjIn, tmp, eventHandle, + t, handleObj, special, + events, handlers, type, namespaces, origType, elemData = jQuery._data( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) @@ -133,8 +133,8 @@ jQuery.event = { // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { - var j, origCount, tmp, - events, t, handleObj, + var events, handleObj, tmp, + j, t, origCount, special, handlers, type, namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); @@ -206,7 +206,7 @@ jQuery.event = { trigger: function( event, data, elem, onlyHandlers ) { - var i, cur, tmp, bubbleType, ontype, handle, special, + var i, handle, ontype, bubbleType, tmp, special, cur, eventPath = [ elem || document ], type = event.type || event, namespaces = event.namespace ? event.namespace.split(".") : []; @@ -343,7 +343,7 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); - var i, j, ret, matched, handleObj, + var ret, j, handleObj, matched, i, handlerQueue = [], args = core_slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], @@ -876,7 +876,7 @@ if ( !jQuery.support.focusinBubbles ) { jQuery.fn.extend({ on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var origFn, type; + var type, origFn; // Types can be a map of types/handlers if ( typeof types === "object" ) { diff --git a/src/manipulation.js b/src/manipulation.js index 569a71d832..b947df8e9b 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -285,7 +285,7 @@ jQuery.fn.extend({ // Flatten any nested arrays args = core_concat.apply( [], args ); - var fragment, first, scripts, hasScripts, node, doc, + var scripts, node, doc, fragment, hasScripts, first, i = 0, l = this.length, set = this, @@ -559,7 +559,7 @@ function fixDefaultChecked( elem ) { jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var destElements, srcElements, node, i, clone, + var clone, node, srcElements, i, destElements, inPage = jQuery.contains( elem.ownerDocument, elem ); if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { @@ -614,7 +614,7 @@ jQuery.extend({ }, buildFragment: function( elems, context, scripts, selection ) { - var contains, elem, tag, tmp, wrap, tbody, j, + var contains, elem, j, tmp, tag, wrap, tbody, l = elems.length, // Ensure a safe fragment @@ -740,7 +740,7 @@ jQuery.extend({ }, cleanData: function( elems, /* internal */ acceptData ) { - var data, id, elem, type, + var elem, id, type, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, From d79bf3517eda9b74883c68c255e82067449d3274 Mon Sep 17 00:00:00 2001 From: Oleg Date: Tue, 29 Jan 2013 04:04:58 +0400 Subject: [PATCH 64/80] Fix #13355. Tweak Uglify options and var order for gzip. Close gh-1151. Change uglify-js options for compressor Change variables initialization sequence for some declarations --- Gruntfile.js | 6 ++++++ src/ajax.js | 28 ++++++++++++++-------------- src/ajax/xhr.js | 6 +----- src/attributes.js | 2 +- src/callbacks.js | 8 ++++---- src/core.js | 10 +++++----- src/css.js | 6 +++--- src/data.js | 7 +++---- src/effects.js | 6 ++++-- src/event.js | 25 ++++++++++++------------- src/manipulation.js | 12 +++++++----- src/support.js | 4 +++- 12 files changed, 63 insertions(+), 57 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 5d72c24ad9..4058871d51 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -101,6 +101,12 @@ module.exports = function( grunt ) { options: { banner: "/*! jQuery v<%= pkg.version %> | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license */", sourceMap: "dist/jquery.min.map", + compress: { + hoist_funs: false, + join_vars: false, + loops: false, + unused: false + }, beautify: { ascii_only: true } diff --git a/src/ajax.js b/src/ajax.js index a7508e9721..04c7e0208a 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -2,7 +2,6 @@ var // Document location ajaxLocParts, ajaxLocation, - ajax_nonce = jQuery.now(), ajax_rquery = /\?/, @@ -115,7 +114,7 @@ function inspectPrefiltersOrTransports( structure, options, originalOptions, jqX // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { - var key, deep, + var deep, key, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { @@ -135,7 +134,7 @@ jQuery.fn.load = function( url, params, callback ) { return _load.apply( this, arguments ); } - var selector, type, response, + var selector, response, type, self = this, off = url.indexOf(" "); @@ -316,20 +315,23 @@ jQuery.extend({ // Force options to be an object options = options || {}; - var transport, + var // Cross-domain detection vars + parts, + // Loop variable + i, // URL without anti-cache param cacheURL, - // Response headers + // Response headers as string responseHeadersString, - responseHeaders, // timeout handle timeoutTimer, - // Cross-domain detection vars - parts, + // To know if global events are to be dispatched fireGlobals, - // Loop variable - i, + + transport, + // Response headers + responseHeaders, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context @@ -704,8 +706,7 @@ jQuery.extend({ * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { - - var ct, type, finalDataType, firstDataType, + var firstDataType, ct, finalDataType, type, contents = s.contents, dataTypes = s.dataTypes, responseFields = s.responseFields; @@ -766,8 +767,7 @@ function ajaxHandleResponses( s, jqXHR, responses ) { // Chain conversions given the request and the original response function ajaxConvert( s, response ) { - - var conv, conv2, current, tmp, + var conv2, current, conv, tmp, converters = {}, i = 0, // Work with a copy of dataTypes in case we need to modify it for conversion diff --git a/src/ajax/xhr.js b/src/ajax/xhr.js index 2353392f6a..3133dd4398 100644 --- a/src/ajax/xhr.js +++ b/src/ajax/xhr.js @@ -101,11 +101,7 @@ if ( xhrSupported ) { // Listener callback = function( _, isAbort ) { - - var status, - statusText, - responseHeaders, - responses; + var status, responseHeaders, statusText, responses; // Firefox throws exceptions when accessing properties // of an xhr when a network error occurred diff --git a/src/attributes.js b/src/attributes.js index 7d4fd94922..6902244edf 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -290,7 +290,7 @@ jQuery.extend({ }, attr: function( elem, name, value ) { - var ret, hooks, notxml, + var hooks, notxml, ret, nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes diff --git a/src/callbacks.js b/src/callbacks.js index 32c22ce59c..d94f0b329e 100644 --- a/src/callbacks.js +++ b/src/callbacks.js @@ -46,12 +46,12 @@ jQuery.Callbacks = function( options ) { memory, // Flag to know if list was already fired fired, - // First callback to fire (used internally by add and fireWith) - firingStart, - // Index of currently firing callback (modified by remove if needed) - firingIndex, // End of the loop when firing firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, // Actual callback list list = [], // Stack of fire calls for repeatable lists diff --git a/src/core.js b/src/core.js index 4098f8fef1..d37056d8dd 100644 --- a/src/core.js +++ b/src/core.js @@ -1,10 +1,10 @@ var - // A central reference to the root jQuery(document) - rootjQuery, - // The deferred used on DOM ready readyList, + // A central reference to the root jQuery(document) + rootjQuery, + // Support: IE<9 // For `typeof node.method` instead of `node.method !== undefined` core_strundefined = typeof undefined, @@ -93,7 +93,7 @@ jQuery.fn = jQuery.prototype = { constructor: jQuery, init: function( selector, context, rootjQuery ) { - var elem, match; + var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { @@ -288,7 +288,7 @@ jQuery.fn = jQuery.prototype = { jQuery.fn.init.prototype = jQuery.fn; jQuery.extend = jQuery.fn.extend = function() { - var copy, options, src, copyIsArray, name, clone, + var src, copyIsArray, copy, name, options, clone, target = arguments[0] || {}, i = 1, length = arguments.length, diff --git a/src/css.js b/src/css.js index 57d61925ec..72a9962d31 100644 --- a/src/css.js +++ b/src/css.js @@ -1,4 +1,4 @@ -var curCSS, getStyles, iframe, +var iframe, getStyles, curCSS, ralpha = /alpha\([^)]*\)/i, ropacity = /opacity\s*=\s*([^)]*)/, rposition = /^(top|right|bottom|left)$/, @@ -98,7 +98,7 @@ function showHide( elements, show ) { jQuery.fn.extend({ css: function( name, value ) { return jQuery.access( this, function( elem, name, value ) { - var styles, len, + var len, styles, map = {}, i = 0; @@ -239,7 +239,7 @@ jQuery.extend({ }, css: function( elem, name, extra, styles ) { - var val, num, hooks, + var num, val, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name diff --git a/src/data.js b/src/data.js index 95aa0dc307..e471df4eaa 100644 --- a/src/data.js +++ b/src/data.js @@ -1,7 +1,7 @@ var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, rmultiDash = /([A-Z])/g; -function internalData( elem, name, data, pvt ) { +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ if ( !jQuery.acceptData( elem ) ) { return; } @@ -100,8 +100,7 @@ function internalRemoveData( elem, name, pvt ) { return; } - var thisCache, i, l, - + var i, l, thisCache, isNode = elem.nodeType, // See jQuery.data for more information @@ -216,7 +215,7 @@ jQuery.extend({ _data: function( elem, name, data ) { return internalData( elem, name, data, true ); }, - + _removeData: function( elem, name ) { return internalRemoveData( elem, name, true ); }, diff --git a/src/effects.js b/src/effects.js index ce7017ef16..5cac7d2d8c 100644 --- a/src/effects.js +++ b/src/effects.js @@ -175,7 +175,7 @@ function Animation( elem, properties, options ) { } function propFilter( props, specialEasing ) { - var index, name, easing, value, hooks; + var value, name, index, easing, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { @@ -243,7 +243,9 @@ jQuery.Animation = jQuery.extend( Animation, { function defaultPrefilter( elem, props, opts ) { /*jshint validthis:true */ - var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + var prop, index, length, + value, dataShow, toggle, + tween, hooks, oldfire, anim = this, style = elem.style, orig = {}, diff --git a/src/event.js b/src/event.js index c10c684df4..3d085d2ef2 100644 --- a/src/event.js +++ b/src/event.js @@ -21,10 +21,9 @@ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { - - var handleObjIn, tmp, eventHandle, - t, handleObj, special, - events, handlers, type, namespaces, origType, + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, elemData = jQuery._data( elem ); // Don't attach events to noData or text/comment nodes (but allow plain objects) @@ -132,10 +131,10 @@ jQuery.event = { // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { - - var events, handleObj, tmp, - j, t, origCount, - special, handlers, type, namespaces, origType, + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ); if ( !elemData || !(events = elemData.events) ) { @@ -205,8 +204,8 @@ jQuery.event = { }, trigger: function( event, data, elem, onlyHandlers ) { - - var i, handle, ontype, bubbleType, tmp, special, cur, + var handle, ontype, cur, + bubbleType, special, tmp, i, eventPath = [ elem || document ], type = event.type || event, namespaces = event.namespace ? event.namespace.split(".") : []; @@ -343,7 +342,7 @@ jQuery.event = { // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( event ); - var ret, j, handleObj, matched, i, + var i, ret, handleObj, matched, j, handlerQueue = [], args = core_slice.call( arguments ), handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], @@ -398,7 +397,7 @@ jQuery.event = { }, handlers: function( event, handlers ) { - var i, matches, sel, handleObj, + var sel, handleObj, matches, i, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; @@ -511,7 +510,7 @@ jQuery.event = { mouseHooks: { props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), filter: function( event, original ) { - var eventDoc, doc, body, + var body, eventDoc, doc, button = original.button, fromElement = original.fromElement; diff --git a/src/manipulation.js b/src/manipulation.js index b947df8e9b..3e14c2b561 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -285,7 +285,8 @@ jQuery.fn.extend({ // Flatten any nested arrays args = core_concat.apply( [], args ); - var scripts, node, doc, fragment, hasScripts, first, + var first, node, hasScripts, + scripts, doc, fragment, i = 0, l = this.length, set = this, @@ -436,7 +437,7 @@ function cloneCopyEvent( src, dest ) { } function fixCloneNodeIssues( src, dest ) { - var nodeName, data, e; + var nodeName, e, data; // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { @@ -559,7 +560,7 @@ function fixDefaultChecked( elem ) { jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var clone, node, srcElements, i, destElements, + var destElements, node, clone, i, srcElements, inPage = jQuery.contains( elem.ownerDocument, elem ); if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { @@ -614,7 +615,8 @@ jQuery.extend({ }, buildFragment: function( elems, context, scripts, selection ) { - var contains, elem, j, tmp, tag, wrap, tbody, + var j, elem, contains, + tmp, tag, tbody, wrap, l = elems.length, // Ensure a safe fragment @@ -740,7 +742,7 @@ jQuery.extend({ }, cleanData: function( elems, /* internal */ acceptData ) { - var elem, id, type, data, + var elem, type, id, data, i = 0, internalKey = jQuery.expando, cache = jQuery.cache, diff --git a/src/support.js b/src/support.js index 09f894c700..6e755b55dd 100644 --- a/src/support.js +++ b/src/support.js @@ -1,6 +1,8 @@ jQuery.support = (function() { - var support, all, a, select, opt, input, fragment, eventName, isSupported, i, + var support, all, a, + input, select, fragment, + opt, eventName, isSupported, i, div = document.createElement("div"); // Setup From f005af54e4983658e3ae504111885921c4dca383 Mon Sep 17 00:00:00 2001 From: Andrew Plummer Date: Thu, 31 Jan 2013 12:01:34 -0600 Subject: [PATCH 65/80] event: Stricter type checking in trigger - Fixes #13360 - Closes gh-1153 Squashed commit of the following: commit 5935a362c75ecef04d5ec9775cbcaf2165921e8d Author: Andrew Plummer Date: Fri Feb 1 02:40:42 2013 +0900 Using "hasOwnProperty" to check for direct properties "type" and "namespace" on events before triggering. --- src/event.js | 4 ++-- test/unit/event.js | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/event.js b/src/event.js index 3d085d2ef2..4681140be2 100644 --- a/src/event.js +++ b/src/event.js @@ -207,8 +207,8 @@ jQuery.event = { var handle, ontype, cur, bubbleType, special, tmp, i, eventPath = [ elem || document ], - type = event.type || event, - namespaces = event.namespace ? event.namespace.split(".") : []; + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; cur = tmp = elem = elem || document; diff --git a/test/unit/event.js b/test/unit/event.js index b252a4654e..c3239f9020 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2674,3 +2674,17 @@ test( "Check order of focusin/focusout events", 2, function() { input.off(); }); +test( "String.prototype.namespace does not cause trigger() to throw (#13360)", function() { + expect( 1 ); + var errored = false; + + String.prototype.namespace = function() {}; + + try { + jQuery("

    ").trigger("foo.bar"); + } catch( e ) { + errored = true; + } + equal( errored, false, "trigger() did not throw exception" ); + delete String.prototype.namespace; +}); From 1923da83140f2628c9abf0dafb09041456f3996b Mon Sep 17 00:00:00 2001 From: Corey Frang Date: Thu, 31 Jan 2013 12:13:50 -0600 Subject: [PATCH 66/80] Adding @andrewplummer to AUTHORS.txt --- AUTHORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS.txt b/AUTHORS.txt index ba8b76e439..cdd78792d0 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -160,3 +160,4 @@ Sebastian Burkhard Danil Somsikov Jean Boussier Adam Coulombe +Andrew Plummer From 7adee6c4da5c89e96b1532b6bd3faa1ee4bfdb2a Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Fri, 1 Feb 2013 17:17:39 -0500 Subject: [PATCH 67/80] Fix #13335. Remove "use strict". --- src/.jshintrc | 1 - src/intro.js | 7 ++++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/.jshintrc b/src/.jshintrc index 72a58de2ea..240302db48 100644 --- a/src/.jshintrc +++ b/src/.jshintrc @@ -4,7 +4,6 @@ "newcap": false, "quotmark": "double", "regexdash": true, - "strict": true, "trailing": true, "undef": true, "unused": true, diff --git a/src/intro.js b/src/intro.js index 4e7b69ec35..98815ad874 100644 --- a/src/intro.js +++ b/src/intro.js @@ -12,4 +12,9 @@ * Date: @DATE */ (function( window, undefined ) { -"use strict"; + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; From fbce702f4bb47ed5cfb2e58e1646fefc2b786a2e Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sat, 2 Feb 2013 22:18:33 -0500 Subject: [PATCH 68/80] Ref #12846 and 3b6d8941d8. Fix unit test for IE6. --- test/unit/effects.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/unit/effects.js b/test/unit/effects.js index 173af5a0e2..e761300a22 100644 --- a/test/unit/effects.js +++ b/test/unit/effects.js @@ -1797,8 +1797,12 @@ test( "Animate properly sets overflow hidden when animating width/height (#12117 equal( div.css( "overflow" ), "hidden", "overflow: hidden set when animating " + prop + " to " + value ); div.stop(); - equal( div.css( "overflow" ), "auto", - "overflow: auto restored after animating " + prop + " to " + value ); + if ( jQuery.support.shrinkWrapBlocks ) { + ok( true, "cannot restore overflow, shrinkWrapBlocks" ); + } else { + equal( div.css( "overflow" ), "auto", + "overflow: auto restored after animating " + prop + " to " + value ); + } }); }); }); From 59dd3d9b95b8bc7b729c72bfcccb660848208e82 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Sun, 3 Feb 2013 12:28:42 -0500 Subject: [PATCH 69/80] Upgrade QUnit: Welcome to the present! --- test/qunit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/qunit b/test/qunit index 900f72051b..6ca3721222 160000 --- a/test/qunit +++ b/test/qunit @@ -1 +1 @@ -Subproject commit 900f72051b0112342feda3d700a7a049d886b9ce +Subproject commit 6ca3721222109997540bd6d9ccd396902e0ad2f9 From 219a1935eea509bf147a05ef9d47502d8230991d Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Sun, 3 Feb 2013 13:54:38 -0500 Subject: [PATCH 70/80] Fix #13089. Only apply zoom to IE6/7 body. --- src/support.js | 9 ++++++--- test/unit/support.js | 9 +++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/support.js b/src/support.js index 6e755b55dd..d955bf0c15 100644 --- a/src/support.js +++ b/src/support.js @@ -219,9 +219,12 @@ jQuery.support = (function() { div.firstChild.style.width = "5px"; support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - body.style.zoom = 1; + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } } body.removeChild( container ); diff --git a/test/unit/support.js b/test/unit/support.js index 356751d22a..60a6582610 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -6,6 +6,15 @@ test("boxModel", function() { equal( jQuery.support.boxModel, document.compatMode === "CSS1Compat" , "jQuery.support.boxModel is sort of tied to quirks mode but unstable since 1.8" ); }); +test( "zoom of doom (#13089)", function() { + expect( 1 ); + + if ( jQuery.support.inlineBlockNeedsLayout ) { + ok( document.body.style.zoom, "Added a zoom to the body (#11048, #12869)" ); + } else { + ok( !document.body.style.zoom, "No zoom added to the body" ); + } +}); if ( jQuery.css ) { testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9239)", "support/bodyBackground.html", function( color, support ) { expect( 2 ); From 8226666b1344b27f22f3f0699586054a20718ad3 Mon Sep 17 00:00:00 2001 From: Oleg Date: Fri, 1 Feb 2013 16:57:50 +0400 Subject: [PATCH 71/80] Fix #13310. Get the right display value for disconnected nodes. Close gh-1155. --- src/css.js | 17 +++++++++++++---- test/data/testsuite.css | 2 ++ test/index.html | 1 + test/unit/css.js | 23 +++++++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/css.js b/src/css.js index 72a9962d31..1d15314528 100644 --- a/src/css.js +++ b/src/css.js @@ -51,7 +51,7 @@ function isHidden( elem, el ) { } function showHide( elements, show ) { - var elem, + var display, elem, hidden, values = [], index = 0, length = elements.length; @@ -61,11 +61,13 @@ function showHide( elements, show ) { if ( !elem.style ) { continue; } + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; if ( show ) { // Reset the inline display of this element to learn if it is // being hidden by cascaded rules or not - if ( !values[ index ] && elem.style.display === "none" ) { + if ( !values[ index ] && display === "none" ) { elem.style.display = ""; } @@ -75,8 +77,15 @@ function showHide( elements, show ) { if ( elem.style.display === "" && isHidden( elem ) ) { values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); } - } else if ( !values[ index ] && !isHidden( elem ) ) { - jQuery._data( elem, "olddisplay", jQuery.css( elem, "display" ) ); + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } } } diff --git a/test/data/testsuite.css b/test/data/testsuite.css index 6bb3a5ded4..1dfa7cd344 100644 --- a/test/data/testsuite.css +++ b/test/data/testsuite.css @@ -151,3 +151,5 @@ section { background:#f0f; display:block; } /* #11971 */ #foo { background: url(1x1.jpg) right bottom no-repeat; } + +#display { display: list-item !important; } diff --git a/test/index.html b/test/index.html index 918d7d2d70..f073054d8f 100644 --- a/test/index.html +++ b/test/index.html @@ -318,6 +318,7 @@

    +
    diff --git a/test/unit/css.js b/test/unit/css.js index f7c7ad424d..303ee55153 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1010,4 +1010,27 @@ asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Eleme window.setTimeout( start, 1000 ); }); +asyncTest( "Make sure initialized display value for disconnected nodes is correct (#13310)", 4, function() { + var display = jQuery("#display").css("display"), + div = jQuery("
    "); + + equal( div.css( "display", "inline" ).hide().show().appendTo("body").css( "display" ), "inline", "Initialized display value has returned" ); + div.remove(); + + div.css( "display", "none" ).hide(); + equal( jQuery._data( div[ 0 ], "olddisplay" ), undefined, "olddisplay is undefined after hiding a detached and hidden element" ); + div.remove(); + + div.css( "display", "inline-block" ).hide().appendTo("body").fadeIn(function() { + equal( div.css( "display" ), "inline-block", "Initialized display value has returned" ); + div.remove(); + + start(); + }); + + equal( jQuery._data( jQuery("#display").css( "display", "inline" ).hide()[ 0 ], "olddisplay" ), display, + "display: * !Important value should used as initialized display" ); + jQuery._removeData( jQuery("#display")[ 0 ] ); +}); + } From f3c776dcc939ef3abe6e6ad11be235c8a61f63cf Mon Sep 17 00:00:00 2001 From: Oleg Date: Tue, 22 Jan 2013 21:58:41 +0400 Subject: [PATCH 72/80] Fix #13356. Clean up after load/ready handlers. Close gh-1152. --- src/core.js | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/core.js b/src/core.js index d37056d8dd..4115c5eae0 100644 --- a/src/core.js +++ b/src/core.js @@ -74,17 +74,25 @@ var return letter.toUpperCase(); }, - // The ready event handler and self cleanup method - DOMContentLoaded = function() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); - jQuery.ready(); - } else if ( document.readyState === "complete" ) { - // we're here because readyState === "complete" in oldIE - // which is good enough for us to call the dom ready! - document.detachEvent( "onreadystatechange", DOMContentLoaded ); + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); jQuery.ready(); } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } }; jQuery.fn = jQuery.prototype = { @@ -869,18 +877,18 @@ jQuery.ready.promise = function( obj ) { // Standards-based browsers support DOMContentLoaded } else if ( document.addEventListener ) { // Use the handy event callback - document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + document.addEventListener( "DOMContentLoaded", completed, false ); // A fallback to window.onload, that will always work - window.addEventListener( "load", jQuery.ready, false ); + window.addEventListener( "load", completed, false ); // If IE event model is used } else { // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", DOMContentLoaded ); + document.attachEvent( "onreadystatechange", completed ); // A fallback to window.onload, that will always work - window.attachEvent( "onload", jQuery.ready ); + window.attachEvent( "onload", completed ); // If IE and not a frame // continually check to see if the document is ready @@ -902,6 +910,9 @@ jQuery.ready.promise = function( obj ) { return setTimeout( doScrollCheck, 50 ); } + // detach all dom ready events + detach(); + // and execute any waiting functions jQuery.ready(); } From 28d946384799abcd7608c3beda898a0a11ac88d7 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 4 Feb 2013 19:56:06 -0500 Subject: [PATCH 73/80] Tagging the 1.9.1 release. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 945e554051..5089c7ffc6 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.1pre", + "version": "1.9.1", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", From ef49a68445e24065ef81d1ff4932a0dd3af18da7 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 4 Feb 2013 19:56:34 -0500 Subject: [PATCH 74/80] Updating the source version to 1.9.2pre --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5089c7ffc6..89e0ed51c7 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "jquery", "title": "jQuery", "description": "JavaScript library for DOM operations", - "version": "1.9.1", + "version": "1.9.2pre", "homepage": "http://jquery.com", "author": { "name": "jQuery Foundation and other contributors", From 3895e3a095d5fed35198bf9bc9a94cdfd9e8ff03 Mon Sep 17 00:00:00 2001 From: Dave Methvin Date: Mon, 4 Feb 2013 19:59:13 -0500 Subject: [PATCH 75/80] 2013! --- src/intro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intro.js b/src/intro.js index 98815ad874..c9b1dcdade 100644 --- a/src/intro.js +++ b/src/intro.js @@ -5,7 +5,7 @@ * Includes Sizzle.js * http://sizzlejs.com/ * - * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * From a8518c3bc4e1a8755c2d3a7be624b0e86be1070b Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Fri, 1 Feb 2013 18:06:02 -0500 Subject: [PATCH 76/80] Update Sizzle: detached node sorting in Webkit. Fixes #13331. --- src/sizzle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sizzle b/src/sizzle index c0d9badeb5..1c8aec9128 160000 --- a/src/sizzle +++ b/src/sizzle @@ -1 +1 @@ -Subproject commit c0d9badeb5dac649d0ba7824efaebbe4155369b5 +Subproject commit 1c8aec91284af8d8c14447976235d5dd72b0d75e From 67a2e4eaac98cee79a02a0a45e4826a7958d4b75 Mon Sep 17 00:00:00 2001 From: Richard Gibson Date: Fri, 8 Feb 2013 00:20:33 -0500 Subject: [PATCH 77/80] Ref #13316: Sync all test documents on full vs. minified source. --- src/support.js | 2 +- test/csp.php | 16 ---- test/data/ajax/unreleasedXHR.html | 2 +- test/data/core/cc_on.html | 2 +- test/data/dimensions/documentLarge.html | 2 +- test/data/dimensions/documentSmall.html | 2 +- test/data/event/promiseReady.html | 2 +- test/data/event/syncReady.html | 2 +- test/data/manipulation/iframe-denied.html | 2 +- test/data/offset/absolute.html | 2 +- test/data/offset/body.html | 2 +- test/data/offset/fixed.html | 2 +- test/data/offset/relative.html | 2 +- test/data/offset/scroll.html | 2 +- test/data/offset/static.html | 2 +- test/data/offset/table.html | 2 +- test/data/selector/html5_selector.html | 2 +- test/data/selector/sizzle_cache.html | 10 +- test/data/support/bodyBackground.html | 2 +- test/data/support/csp.js | 3 + test/data/support/csp.php | 22 +++++ test/data/support/shrinkWrapBlocks.html | 2 +- test/data/support/testElementCrash.html | 2 +- test/delegatetest.html | 2 +- test/hovertest.html | 2 +- test/index.html | 2 +- test/jquery.js | 5 + test/localfile.html | 2 +- test/networkerror.html | 2 +- test/polluted.php | 110 ---------------------- test/readywait.html | 2 +- test/unit/selector.js | 3 +- test/unit/support.js | 32 +++---- 33 files changed, 76 insertions(+), 175 deletions(-) delete mode 100644 test/csp.php create mode 100644 test/data/support/csp.js create mode 100644 test/data/support/csp.php create mode 100644 test/jquery.js delete mode 100644 test/polluted.php diff --git a/src/support.js b/src/support.js index d955bf0c15..f677c0963e 100644 --- a/src/support.js +++ b/src/support.js @@ -133,7 +133,7 @@ jQuery.support = (function() { } // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) for ( i in { submit: true, change: true, focusin: true }) { div.setAttribute( eventName = "on" + i, "t" ); diff --git a/test/csp.php b/test/csp.php deleted file mode 100644 index 9ab18f3920..0000000000 --- a/test/csp.php +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - CSP Test Page - - - - -

    CSP Test Page

    - - diff --git a/test/data/ajax/unreleasedXHR.html b/test/data/ajax/unreleasedXHR.html index 6c3d8210b1..5233354f57 100644 --- a/test/data/ajax/unreleasedXHR.html +++ b/test/data/ajax/unreleasedXHR.html @@ -3,7 +3,7 @@ Attempt to block tests because of dangling XHR requests (IE) - + - + +
    diff --git a/test/data/dimensions/documentSmall.html b/test/data/dimensions/documentSmall.html index 12cbf93855..63e1c2a8ff 100644 --- a/test/data/dimensions/documentSmall.html +++ b/test/data/dimensions/documentSmall.html @@ -15,7 +15,7 @@
    - +
    diff --git a/test/data/event/promiseReady.html b/test/data/event/promiseReady.html index d2b166f322..17b6e7f2c6 100644 --- a/test/data/event/promiseReady.html +++ b/test/data/event/promiseReady.html @@ -3,7 +3,7 @@ Test case for jQuery ticket #11470 - + + diff --git a/test/data/manipulation/iframe-denied.html b/test/data/manipulation/iframe-denied.html index 28a5305759..14df26a69b 100644 --- a/test/data/manipulation/iframe-denied.html +++ b/test/data/manipulation/iframe-denied.html @@ -6,7 +6,7 @@
    - + + + + + + + + + + - - - diff --git a/test/data/support/bodyBackground.html b/test/data/support/bodyBackground.html index b0abc074fe..8991007cf7 100644 --- a/test/data/support/bodyBackground.html +++ b/test/data/support/bodyBackground.html @@ -17,7 +17,7 @@
    - +
    + + + +

    CSP Test Page

    + + diff --git a/test/data/support/shrinkWrapBlocks.html b/test/data/support/shrinkWrapBlocks.html index 1ae15bfb56..a2097cb21c 100644 --- a/test/data/support/shrinkWrapBlocks.html +++ b/test/data/support/shrinkWrapBlocks.html @@ -12,7 +12,7 @@
    - +
    + + - + \n"; - if( $lib == "prototype" ) { // prototype must be included first - array_unshift( $includes, $include ); - } else { - array_push( $includes, $include ); - } - } - - $includes = implode( "\n", $includes ); - $suite = file_get_contents( "index.html" ); - echo str_replace( "", $includes, $suite ); - exit; - } -?> - - - - - Run jQuery Test Suite Polluted - - - - -

    jQuery Test Suite

    - -

    Choose other libraries to include

    - -
    - $data ) { - echo "
    $name"; - $i = 0; - foreach( $data[ "versions" ] as $ver ) { - $i++; - echo ""; - if( !($i % 4) ) echo "
    "; - } - echo "
    "; - } - ?> - -
    - - diff --git a/test/readywait.html b/test/readywait.html index 4738b1b952..7a736bef5a 100644 --- a/test/readywait.html +++ b/test/readywait.html @@ -14,7 +14,7 @@ #output { background-color: green } #expectedOutput { background-color: green } - + diff --git a/test/unit/selector.js b/test/unit/selector.js index 07e563da3a..22d7305eb0 100644 --- a/test/unit/selector.js +++ b/test/unit/selector.js @@ -178,7 +178,8 @@ testIframe("selector/html5_selector", "attributes - jQuery.attr", function( jQue testIframe("selector/sizzle_cache", "Sizzle cache collides with multiple Sizzles on a page", function( jQuery, window, document ) { var $cached = window["$cached"]; - expect(3); + expect(4); + notStrictEqual( jQuery, $cached, "Loaded two engines" ); deepEqual( $cached(".test a").get(), [ document.getElementById("collision") ], "Select collision anchor with first sizzle" ); equal( jQuery(".evil a").length, 0, "Select nothing with second sizzle" ); equal( jQuery(".evil a").length, 0, "Select nothing again with second sizzle" ); diff --git a/test/unit/support.js b/test/unit/support.js index 60a6582610..4c6a49d553 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -18,33 +18,18 @@ test( "zoom of doom (#13089)", function() { if ( jQuery.css ) { testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9239)", "support/bodyBackground.html", function( color, support ) { expect( 2 ); - var i, - passed = true, - okValue = { + var okValue = { "#000000": true, "rgb(0, 0, 0)": true }; ok( okValue[ color ], "color was not reset (" + color + ")" ); - for ( i in jQuery.support ) { - if ( jQuery.support[ i ] !== support[ i ] ) { - passed = false; - strictEqual( jQuery.support[ i ], support[ i ], "Support property " + i + " is different" ); - } - } - for ( i in support ) { - if ( !( i in jQuery.support ) ) { - passed = false; - strictEqual( jQuery.support[ i ], support[ i ], "Unexpected property: " + i ); - } - } - - ok( passed, "Same support properties" ); + deepEqual( jQuery.extend( {}, support ), jQuery.support, "Same support properties" ); }); } testIframeWithCallback( "A background on the testElement does not cause IE8 to crash (#9823)", "support/testElementCrash.html", function() { - expect(1); + expect( 1 ); ok( true, "IE8 does not crash" ); }); @@ -382,3 +367,14 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo } })(); + +// Support: Safari 5.1 +// Shameless browser-sniff, but Safari 5.1 mishandles CSP +if ( !( typeof navigator !== "undefined" && + (/ AppleWebKit\/\d.*? Version\/(\d+)/.exec(navigator.userAgent) || [])[1] < 6 ) ) { + + testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Security/CSP) restrictions", "support/csp.php", function( support ) { + expect( 1 ); + deepEqual( jQuery.extend( {}, support ), jQuery.support, "No violations of CSP polices" ); + }); +} From 03ab9b9f9061df1cf38fd6466c2241dfb2ae9cdc Mon Sep 17 00:00:00 2001 From: Mark Raddatz Date: Fri, 8 Feb 2013 05:43:25 +0800 Subject: [PATCH 78/80] Fix #13401: replaceWith(""). Close gh-1163. (cherry picked from commit 6a0ee2d9ed34b81d4ad0662423bf815a3110990f) --- src/manipulation.js | 20 +++++++++++--------- test/unit/manipulation.js | 9 +++++++++ 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/manipulation.js b/src/manipulation.js index 3e14c2b561..3a4f9a6881 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -265,15 +265,17 @@ jQuery.fn.extend({ value = jQuery( value ).not( this ).detach(); } - return this.domManip( [ value ], true, function( elem ) { - var next = this.nextSibling, - parent = this.parentNode; - - if ( parent ) { - jQuery( this ).remove(); - parent.insertBefore( elem, next ); - } - }); + return value !== "" ? + this.domManip( [ value ], true, function( elem ) { + var next = this.nextSibling, + parent = this.parentNode; + + if ( parent ) { + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + }) : + this.remove(); }, detach: function( selector ) { diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 73313ea971..b0736fbf6b 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1261,6 +1261,15 @@ test( "replaceWith(string) for more than one element", function() { equal(jQuery("#foo p").length, 0, "verify that all the three original element have been replaced"); }); +test( "replaceWith(\"\") (#13401)", 4, function() { + expect( 1 ); + + var div = jQuery("

    "); + + div.children().replaceWith(""); + equal( div.html().toLowerCase(), "", "Replacing with empty string removes element" ); +}); + test( "replaceAll(String|Element|Array|jQuery)", function() { expect( 10 ); From c0c38adc1e4a1e5567312132fec8dbf4b0f63e03 Mon Sep 17 00:00:00 2001 From: jaubourg Date: Fri, 8 Feb 2013 16:26:36 +0100 Subject: [PATCH 79/80] Minor refactor of response conversion and when/where responseXXX fields are set on the jqXHR. Fixes #11151. Fixes #13388. --- src/ajax.js | 83 +++++++++++++++++++------------------ test/data/errorWithJSON.php | 6 +++ test/unit/ajax.js | 22 ++++++++++ 3 files changed, 70 insertions(+), 41 deletions(-) create mode 100644 test/data/errorWithJSON.php diff --git a/src/ajax.js b/src/ajax.js index 04c7e0208a..5fe53aae94 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -257,7 +257,8 @@ jQuery.extend({ responseFields: { xml: "responseXML", - text: "responseText" + text: "responseText", + json: "responseJSON" }, // Data converters @@ -606,13 +607,19 @@ jQuery.extend({ // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + // If successful, handle type chaining - if ( status >= 200 && status < 300 || status === 304 ) { + if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { @@ -628,20 +635,17 @@ jQuery.extend({ // if no content if ( status === 204 ) { - isSuccess = true; statusText = "nocontent"; // if not modified } else if ( status === 304 ) { - isSuccess = true; statusText = "notmodified"; // If we have data, let's convert it } else { - isSuccess = ajaxConvert( s, response ); - statusText = isSuccess.state; - success = isSuccess.data; - error = isSuccess.error; + statusText = response.state; + success = response.data; + error = response.error; isSuccess = !error; } } else { @@ -701,22 +705,13 @@ jQuery.extend({ }); /* Handles responses to an ajax request: - * - sets all responseXXX fields accordingly * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var firstDataType, ct, finalDataType, type, contents = s.contents, - dataTypes = s.dataTypes, - responseFields = s.responseFields; - - // Fill responseXXX fields - for ( type in responseFields ) { - if ( type in responses ) { - jqXHR[ responseFields[type] ] = responses[ type ]; - } - } + dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while( dataTypes[ 0 ] === "*" ) { @@ -765,19 +760,14 @@ function ajaxHandleResponses( s, jqXHR, responses ) { } } -// Chain conversions given the request and the original response -function ajaxConvert( s, response ) { - var conv2, current, conv, tmp, +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, converters = {}, - i = 0, // Work with a copy of dataTypes in case we need to modify it for conversion - dataTypes = s.dataTypes.slice(), - prev = dataTypes[ 0 ]; - - // Apply the dataFilter if provided - if ( s.dataFilter ) { - response = s.dataFilter( response, s.dataType ); - } + dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { @@ -786,14 +776,29 @@ function ajaxConvert( s, response ) { } } - // Convert to each sequential dataType, tolerating list modification - for ( ; (current = dataTypes[++i]); ) { + // Convert to each sequential dataType + for ( current = dataTypes.shift(); current; ) { - // There's only work to do if current dataType is non-auto - if ( current !== "*" ) { + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + + if ( ( current = dataTypes.shift() ) ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; // Convert response if prev dataType is non-auto and differs from current - if ( prev !== "*" && prev !== current ) { + } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; @@ -803,7 +808,7 @@ function ajaxConvert( s, response ) { for ( conv2 in converters ) { // If conv2 outputs current - tmp = conv2.split(" "); + tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input @@ -817,9 +822,8 @@ function ajaxConvert( s, response ) { // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; - dataTypes.splice( i--, 0, current ); + dataTypes.unshift( tmp[ 1 ] ); } - break; } } @@ -830,7 +834,7 @@ function ajaxConvert( s, response ) { if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them - if ( conv && s["throws"] ) { + if ( conv && s[ "throws" ] ) { response = conv( response ); } else { try { @@ -841,9 +845,6 @@ function ajaxConvert( s, response ) { } } } - - // Update prev for next iteration - prev = current; } } diff --git a/test/data/errorWithJSON.php b/test/data/errorWithJSON.php new file mode 100644 index 0000000000..62b187ecc9 --- /dev/null +++ b/test/data/errorWithJSON.php @@ -0,0 +1,6 @@ + Date: Fri, 8 Feb 2013 16:57:34 +0100 Subject: [PATCH 80/80] Makes the code a little more readable while saving 1 byte. Per @gibson042. --- src/ajax.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ajax.js b/src/ajax.js index 5fe53aae94..69b3d60336 100644 --- a/src/ajax.js +++ b/src/ajax.js @@ -776,8 +776,10 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) { } } + current = dataTypes.shift(); + // Convert to each sequential dataType - for ( current = dataTypes.shift(); current; ) { + while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; @@ -789,8 +791,9 @@ function ajaxConvert( s, response, jqXHR, isSuccess ) { } prev = current; + current = dataTypes.shift(); - if ( ( current = dataTypes.shift() ) ) { + if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) {