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

1.7/callbacks^2
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,
rfocusable = /^(?:button|input|object|select|textarea)$/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 = /\:/,
formHook, boolHook;
@ -219,7 +219,8 @@ jQuery.extend({
},
select: {
get: function( elem ) {
var index = elem.selectedIndex,
var value,
index = elem.selectedIndex,
values = [],
options = elem.options,
one = elem.type === "select-one";
@ -310,15 +311,15 @@ jQuery.extend({
hooks = jQuery.attrHooks[ name ];
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
} else if ( rboolean.test( name ) &&
(typeof value === "boolean" || value === undefined) ) {
if ( rboolean.test( name ) &&
(typeof value === "boolean" || value === undefined || value.toLowerCase() === name.toLowerCase()) ) {
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 ) {
var propName;
if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name;
@ -363,8 +365,8 @@ jQuery.extend({
}
// Set corresponding property to false for boolean attributes
if ( rboolean.test( name ) ) {
elem[ jQuery.propFix[ name ] || name ] = false;
if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) {
elem[ propName ] = false;
}
}
},
@ -464,13 +466,19 @@ boolHook = {
undefined;
},
set: function( elem, value, name ) {
var propName;
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else {
// 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
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() );
}
return name;
@ -487,12 +495,9 @@ if ( !jQuery.support.getSetAttribute ) {
formHook = jQuery.attrHooks.name = jQuery.attrHooks.value = jQuery.valHooks.button = {
get: function( elem, name ) {
var ret;
if ( name === "value" && !jQuery.nodeName( elem, "button" ) ) {
return elem.getAttribute( name );
}
ret = elem.getAttributeNode( name );
// Return undefined if not specified instead of empty string
return ret && ret.specified ?
// Return undefined if nodeValue is empty string
return ret && ret.nodeValue !== "" ?
ret.nodeValue :
undefined;
},

View File

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

37
src/effects.js vendored
View File

@ -126,6 +126,9 @@ jQuery.fn.extend({
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() {
// XXX 'this' does not always have a nodeName when running the
// test suite
@ -134,7 +137,7 @@ jQuery.fn.extend({
jQuery._mark( this );
}
var opt = jQuery.extend({}, optall),
var opt = jQuery.extend( {}, optall ),
isElement = this.nodeType === 1,
hidden = isElement && jQuery(this).is(":hidden"),
name, val, p,
@ -153,10 +156,18 @@ jQuery.fn.extend({
delete prop[ p ];
}
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 ) {
return opt.complete.call(this);
return opt.complete.call( this );
}
if ( isElement && ( name === "height" || name === "width" ) ) {
@ -175,7 +186,7 @@ jQuery.fn.extend({
this.style.display = "inline-block";
} else {
display = defaultDisplay(this.nodeName);
display = defaultDisplay( this.nodeName );
// inline-level elements accept inline-block;
// block-level elements need to be inline with layout
@ -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 ) {
@ -202,19 +208,18 @@ jQuery.fn.extend({
for ( p in prop ) {
e = new jQuery.fx( this, opt, p );
val = prop[p];
val = prop[ p ];
if ( rfxtypes.test(val) ) {
e[ val === "toggle" ? hidden ? "show" : "hide" : val ]();
} else {
parts = rfxnum.exec(val);
parts = rfxnum.exec( val );
start = e.cur();
if ( parts ) {
end = parseFloat( parts[2] );
unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" );
unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
// We need to compute starting value
if ( unit !== "px" ) {
@ -225,7 +230,7 @@ jQuery.fn.extend({
// If a +=/-= token was provided, we're doing a relative animation
if ( parts[1] ) {
end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
}
e.custom( start, end, unit );
@ -501,10 +506,10 @@ jQuery.fx.prototype = {
this.now = t;
} else {
n = t - this.startTime;
this.state = n / options.duration;
// 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);
}
// Perform the next step of the animation

View File

@ -138,13 +138,13 @@ test("attr(Hash)", function() {
if ( this.getAttribute("foo") != "baz" && this.getAttribute("zoo") != "ping" ) pass = false;
});
ok( pass, "Set Multiple Attributes" );
equals( jQuery("#text1").attr({value: function() { return this.id; }})[0].value, "text1", "Set attribute to computed value #1" );
equals( jQuery("#text1").attr({title: function(i) { return i; }}).attr("title"), "0", "Set attribute to computed value #2");
equals( jQuery("#text1").attr({value: function() { return this.id; }})[0].value, "text1", "Set attribute to computed value #1" );
equals( jQuery("#text1").attr({title: function(i) { return i; }}).attr("title"), "0", "Set attribute to computed value #2");
});
test("attr(String, Object)", function() {
expect(57);
expect(59);
var div = jQuery("div").attr("foo", "bar"),
fail = false;
@ -164,6 +164,8 @@ test("attr(String, Object)", function() {
equals( jQuery("#name").attr("name"), "something", "Set name attribute" );
jQuery("#name").attr("name", null);
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);
equals( document.getElementById("check2").checked, true, "Set checked attribute" );
@ -209,7 +211,11 @@ test("attr(String, Object)", function() {
$p.removeAttr("nonexisting");
var $text = jQuery("#text1").attr("autofocus", true);
equals( $text.attr("autofocus"), "autofocus", "Set boolean attributes to the same name");
if ( "autofocus" in $text[0] ) {
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("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" );
@ -238,6 +244,8 @@ test("attr(String, Object)", function() {
table.attr("cellspacing", "2");
equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" );
equals( jQuery("#area1").attr("value"), undefined, "Value attribute retrieved correctly on textarea." );
// for #1070
jQuery("#name").attr("someAttr", "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)." );
});
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
$ele = jQuery( ele );
var $ele = jQuery( ele );
$ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
});

76
test/unit/effects.js vendored
View File

@ -32,7 +32,8 @@ test("show()", function() {
hiddendiv.css("display","");
var pass = true, div = jQuery("#qunit-fixture div");
var pass = true;
div = jQuery("#qunit-fixture div");
div.show().each(function(){
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.");
start();
}
};
test( "jQuery.fx.prototype.cur()", 6, function() {
var div = jQuery( "<div></div>" ).appendTo( "#qunit-fixture" ).css({
@ -694,8 +695,8 @@ jQuery.each( {
jQuery(elem).css(prop,prop == "opacity" ? 0 : "0px");
return 0;
}
}, function(fn, f){
jQuery.each( {
}, function( fn, f ) {
jQuery.each({
"show": function(elem,prop){
jQuery(elem).hide().addClass("wide"+prop);
return "show";
@ -901,7 +902,7 @@ jQuery.makeTest = function( text ){
.after( elem );
return elem;
}
};
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(){
expect(3);
expect(5);
stop();
var _test1_called = false;
var _test2_called = false;
var _default_test_called = false;
var data = { a:0, b:0, c:0 },
_test1_called = false,
_test2_called = false,
_default_test_called = false,
props = {
a: [ 100, "_test1" ],
b: [ 100, "_test2" ],
c: 100
};
jQuery.easing["_test1"] = function() {
jQuery.easing["_test1"] = function(p) {
_test1_called = true;
return p;
};
jQuery.easing["_test2"] = function() {
jQuery.easing["_test2"] = function(p) {
_test2_called = true;
return p;
};
jQuery.easing["_default_test"] = function() {
jQuery.easing["_default_test"] = function(p) {
_default_test_called = true;
return p;
};
jQuery({a:0,b:0,c:0}).animate({
a: [100, "_test1"],
b: [100, "_test2"],
c: 100
}, 400, "_default_test", function(){
jQuery(data).animate( props, 400, "_default_test", function(){
start();
ok(_test1_called, "Easing function (1) called");
ok(_test2_called, "Easing function (2) called");
ok(_default_test_called, "Easing function (_default) called");
ok( _test1_called, "Easing function (_test1) called" );
ok( _test2_called, "Easing function (_test2) 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();
});
});
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);
});