Merge branch 'master' of github.com:jquery/jquery into 1.7/callbacks

This commit is contained in:
jaubourg 2011-05-08 16:16:19 +02:00
commit 0de05611bb
5 changed files with 112 additions and 58 deletions

View file

@ -6,7 +6,7 @@ var rclass = /[\n\t\r]/g,
rtype = /^(?:button|input)$/i, rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i,
rclickable = /^a(?:rea)?$/i, rclickable = /^a(?:rea)?$/i,
rboolean = /^(?:autofocus|autoplay|async|checked|controls|declare|defer|disabled|draggable|formnovalidate|hidden|ismap|loop|multiple|muted|noresize|noshade|nowrap|novalidate|open|pubdate|readonly|required|reversed|scoped|seamless|selected|truespeed)$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
rinvalidChar = /\:/, rinvalidChar = /\:/,
formHook, boolHook; formHook, boolHook;
@ -219,7 +219,8 @@ jQuery.extend({
}, },
select: { select: {
get: function( elem ) { get: function( elem ) {
var index = elem.selectedIndex, var value,
index = elem.selectedIndex,
values = [], values = [],
options = elem.options, options = elem.options,
one = elem.type === "select-one"; one = elem.type === "select-one";
@ -310,15 +311,15 @@ jQuery.extend({
hooks = jQuery.attrHooks[ name ]; hooks = jQuery.attrHooks[ name ];
if ( !hooks ) { if ( !hooks ) {
// Use formHook for forms and if the name contains certain characters
if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
hooks = formHook;
// Use boolHook for boolean attributes // Use boolHook for boolean attributes
} else if ( rboolean.test( name ) && if ( rboolean.test( name ) &&
(typeof value === "boolean" || value === undefined) ) { (typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
hooks = boolHook; hooks = boolHook;
// Use formHook for forms and if the name contains certain characters
} else if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
hooks = formHook;
} }
} }
@ -351,6 +352,7 @@ jQuery.extend({
}, },
removeAttr: function( elem, name ) { removeAttr: function( elem, name ) {
var propName;
if ( elem.nodeType === 1 ) { if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name; name = jQuery.attrFix[ name ] || name;
@ -363,8 +365,8 @@ jQuery.extend({
} }
// Set corresponding property to false for boolean attributes // Set corresponding property to false for boolean attributes
if ( rboolean.test( name ) ) { if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
elem[ jQuery.propFix[ name ] || name ] = false; elem[ propName ] = false;
} }
} }
}, },
@ -464,13 +466,19 @@ boolHook = {
undefined; undefined;
}, },
set: function( elem, value, name ) { set: function( elem, value, name ) {
var propName;
if ( value === false ) { if ( value === false ) {
// Remove boolean attributes when set to false // Remove boolean attributes when set to false
jQuery.removeAttr( elem, name ); jQuery.removeAttr( elem, name );
} else { } else {
// value is true since we know at this point it's type boolean and not false // value is true since we know at this point it's type boolean and not false
// Set boolean attributes to the same name and set the DOM property // Set boolean attributes to the same name and set the DOM property
elem[ jQuery.propFix[ name ] || name ] = value; propName = jQuery.propFix[ name ] || name;
if ( propName in elem ) {
// Only set the IDL specifically if it already exists on the element
elem[ propName ] = value;
}
elem.setAttribute( name, name.toLowerCase() ); elem.setAttribute( name, name.toLowerCase() );
} }
return name; return name;
@ -487,12 +495,9 @@ if ( !jQuery.support.getSetAttribute ) {
formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = { formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
get: function( elem, name ) { get: function( elem, name ) {
var ret; var ret;
if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
return elem.getAttribute( name );
}
ret = elem.getAttributeNode( name ); ret = elem.getAttributeNode( name );
// Return undefined if not specified instead of empty string // Return undefined if nodeValue is empty string
return ret && ret.specified ? return ret && ret.nodeValue !== "" ?
ret.nodeValue : ret.nodeValue :
undefined; undefined;
}, },

View file

@ -284,7 +284,7 @@ function dataAttr( elem, key, data ) {
// If nothing was found internally, try to fetch any // If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute // data from the HTML5 data-* attribute
if ( data === undefined && elem.nodeType === 1 ) { if ( data === undefined && elem.nodeType === 1 ) {
name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
data = elem.getAttribute( name ); data = elem.getAttribute( name );

21
src/effects.js vendored
View file

@ -126,6 +126,9 @@ jQuery.fn.extend({
return this.each( optall.complete, [ false ] ); return this.each( optall.complete, [ false ] );
} }
// Do not change referenced properties as per-property easing will be lost
prop = jQuery.extend( {}, prop );
return this[ optall.queue === false ? "each" : "queue" ](function() { return this[ optall.queue === false ? "each" : "queue" ](function() {
// XXX 'this' does not always have a nodeName when running the // XXX 'this' does not always have a nodeName when running the
// test suite // test suite
@ -155,6 +158,14 @@ jQuery.fn.extend({
val = prop[ name ]; val = prop[ name ];
// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
if ( jQuery.isArray( val ) ) {
opt.animatedProperties[ name ] = val[ 1 ];
val = prop[ name ] = val[ 0 ];
} else {
opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
}
if ( val === "hide" && hidden || val === "show" && !hidden ) { if ( val === "hide" && hidden || val === "show" && !hidden ) {
return opt.complete.call( this ); return opt.complete.call( this );
} }
@ -189,11 +200,6 @@ jQuery.fn.extend({
} }
} }
} }
// easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
opt.animatedProperties[name] = jQuery.isArray( val ) ?
val[1]:
opt.specialEasing && opt.specialEasing[name] || opt.easing || 'swing';
} }
if ( opt.overflow != null ) { if ( opt.overflow != null ) {
@ -202,7 +208,6 @@ jQuery.fn.extend({
for ( p in prop ) { for ( p in prop ) {
e = new jQuery.fx( this, opt, p ); e = new jQuery.fx( this, opt, p );
val = prop[ p ]; val = prop[ p ];
if ( rfxtypes.test(val) ) { if ( rfxtypes.test(val) ) {
@ -214,7 +219,7 @@ jQuery.fn.extend({
if ( parts ) { if ( parts ) {
end = parseFloat( parts[2] ); end = parseFloat( parts[2] );
unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
// We need to compute starting value // We need to compute starting value
if ( unit !== "px" ) { if ( unit !== "px" ) {
@ -501,8 +506,8 @@ jQuery.fx.prototype = {
this.now = t; this.now = t;
} else { } else {
n = t - this.startTime; n = t - this.startTime;
this.state = n / options.duration; this.state = n / options.duration;
// Perform the easing function, defaults to swing // Perform the easing function, defaults to swing
this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration );
this.now = this.start + ((this.end - this.start) * this.pos); this.now = this.start + ((this.end - this.start) * this.pos);

View file

@ -144,7 +144,7 @@ test("attr(Hash)", function() {
}); });
test("attr(String, Object)", function() { test("attr(String, Object)", function() {
expect(57); expect(59);
var div = jQuery("div").attr("foo", "bar"), var div = jQuery("div").attr("foo", "bar"),
fail = false; fail = false;
@ -164,6 +164,8 @@ test("attr(String, Object)", function() {
equals( jQuery("#name").attr("name"), "something", "Set name attribute" ); equals( jQuery("#name").attr("name"), "something", "Set name attribute" );
jQuery("#name").attr("name", null); jQuery("#name").attr("name", null);
equals( jQuery("#name").attr("name"), undefined, "Remove name attribute" ); equals( jQuery("#name").attr("name"), undefined, "Remove name attribute" );
var $input = jQuery("<input>", { name: "something" });
equals( $input.attr("name"), "something", "Check element creation gets/sets the name attribute." );
jQuery("#check2").prop("checked", true).prop("checked", false).attr("checked", true); jQuery("#check2").prop("checked", true).prop("checked", false).attr("checked", true);
equals( document.getElementById("check2").checked, true, "Set checked attribute" ); equals( document.getElementById("check2").checked, true, "Set checked attribute" );
@ -209,7 +211,11 @@ test("attr(String, Object)", function() {
$p.removeAttr("nonexisting"); $p.removeAttr("nonexisting");
var $text = jQuery("#text1").attr("autofocus", true); var $text = jQuery("#text1").attr("autofocus", true);
if ( "autofocus" in $text[0] ) {
equals( $text.attr("autofocus"), "autofocus", "Set boolean attributes to the same name"); equals( $text.attr("autofocus"), "autofocus", "Set boolean attributes to the same name");
} else {
equals( $text.attr("autofocus"), undefined, "autofocus stays undefined in browsers that do not support it(F<4)");
}
equals( $text.attr("autofocus", false).attr("autofocus"), undefined, "Setting autofocus attribute to false removes it"); equals( $text.attr("autofocus", false).attr("autofocus"), undefined, "Setting autofocus attribute to false removes it");
equals( $text.attr("data-something", true).data("something"), true, "Setting data attributes are not affected by boolean settings"); equals( $text.attr("data-something", true).data("something"), true, "Setting data attributes are not affected by boolean settings");
equals( $text.attr("data-another", false).data("another"), false, "Setting data attributes are not affected by boolean settings" ); equals( $text.attr("data-another", false).data("another"), false, "Setting data attributes are not affected by boolean settings" );
@ -238,6 +244,8 @@ test("attr(String, Object)", function() {
table.attr("cellspacing", "2"); table.attr("cellspacing", "2");
equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" ); equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" );
equals( jQuery("#area1").attr("value"), undefined, "Value attribute retrieved correctly on textarea." );
// for #1070 // for #1070
jQuery("#name").attr("someAttr", "0"); jQuery("#name").attr("someAttr", "0");
equals( jQuery("#name").attr("someAttr"), "0", "Set attribute to a string of \"0\"" ); equals( jQuery("#name").attr("someAttr"), "0", "Set attribute to a string of \"0\"" );
@ -500,7 +508,7 @@ test("removeProp(String)", function() {
strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." ); strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
}); });
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) { jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
$ele = jQuery( ele ); var $ele = jQuery( ele );
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" ); $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." ); strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
}); });

84
test/unit/effects.js vendored
View file

@ -32,7 +32,8 @@ test("show()", function() {
hiddendiv.css("display",""); hiddendiv.css("display","");
var pass = true, div = jQuery("#qunit-fixture div"); var pass = true;
div = jQuery("#qunit-fixture div");
div.show().each(function(){ div.show().each(function(){
if ( this.style.display == "none" ) pass = false; if ( this.style.display == "none" ) pass = false;
}); });
@ -582,7 +583,7 @@ jQuery.checkOverflowDisplay = function(){
equals(jQuery.css( this, "display" ), "inline", "Display shouldn't be tampered with."); equals(jQuery.css( this, "display" ), "inline", "Display shouldn't be tampered with.");
start(); start();
} };
test( "jQuery.fx.prototype.cur()", 6, function() { test( "jQuery.fx.prototype.cur()", 6, function() {
var div = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" ).css({ var div = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" ).css({
@ -901,7 +902,7 @@ jQuery.makeTest = function( text ){
.after( elem ); .after( elem );
return elem; return elem;
} };
jQuery.makeTest.id = 1; jQuery.makeTest.id = 1;
@ -922,34 +923,42 @@ test("jQuery.show('fast') doesn't clear radio buttons (bug #1095)", function ()
test("animate with per-property easing", function(){ test("animate with per-property easing", function(){
expect(3); expect(5);
stop(); stop();
var _test1_called = false; var data = { a:0, b:0, c:0 },
var _test2_called = false; _test1_called = false,
var _default_test_called = false; _test2_called = false,
_default_test_called = false,
jQuery.easing["_test1"] = function() { props = {
_test1_called = true;
};
jQuery.easing["_test2"] = function() {
_test2_called = true;
};
jQuery.easing["_default_test"] = function() {
_default_test_called = true;
};
jQuery({a:0,b:0,c:0}).animate({
a: [ 100, "_test1" ], a: [ 100, "_test1" ],
b: [ 100, "_test2" ], b: [ 100, "_test2" ],
c: 100 c: 100
}, 400, "_default_test", function(){ };
jQuery.easing["_test1"] = function(p) {
_test1_called = true;
return p;
};
jQuery.easing["_test2"] = function(p) {
_test2_called = true;
return p;
};
jQuery.easing["_default_test"] = function(p) {
_default_test_called = true;
return p;
};
jQuery(data).animate( props, 400, "_default_test", function(){
start(); start();
ok(_test1_called, "Easing function (1) called");
ok(_test2_called, "Easing function (2) called"); ok( _test1_called, "Easing function (_test1) called" );
ok( _test2_called, "Easing function (_test2) called" );
ok( _default_test_called, "Easing function (_default) called" ); ok( _default_test_called, "Easing function (_default) called" );
equal( props.a[ 1 ], "_test1", "animate does not change original props (per-property easing would be lost)");
equal( props.b[ 1 ], "_test2", "animate does not change original props (per-property easing would be lost)");
}); });
}); });
@ -993,3 +1002,30 @@ test("animate unit-less properties (#4966)", 2, function() {
start(); start();
}); });
}); });
test( "animate properties missing px w/ opacity as last (#9074)", 2, function() {
expect( 6 );
stop();
var div = jQuery( "<div style='position: absolute; margin-left: 0; left: 0px;'></div>" )
.appendTo( "#qunit-fixture" );
function cssInt( prop ) {
return parseInt( div.css( prop ), 10 );
}
equal( cssInt( "marginLeft" ), 0, "Margin left is 0" );
equal( cssInt( "left" ), 0, "Left is 0" );
div.animate({
left: 200,
marginLeft: 200,
opacity: 0
}, 1000);
setTimeout(function() {
var ml = cssInt( "marginLeft" ),
l = cssInt( "left" );
notEqual( ml, 0, "Margin left is not 0 after partial animate" );
notEqual( ml, 200, "Margin left is not 200 after partial animate" );
notEqual( l, 0, "Left is not 0 after partial animate" );
notEqual( l, 200, "Left is not 200 after partial animate" );
div.stop().remove();
start();
}, 100);
});