Skip to content

Commit

Permalink
A first pass at making sure that all the setter function arguments re…
Browse files Browse the repository at this point in the history
…ceive the index of the element and a relevant value to work with. Fixes #5763.
  • Loading branch information
jeresig committed Jan 6, 2010
1 parent 84dd82e commit 600d314
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 60 deletions.
114 changes: 62 additions & 52 deletions src/attributes.js
Expand Up @@ -12,10 +12,27 @@ jQuery.fn.extend({
return access( this, name, value, true, jQuery.attr );
},

removeAttr: function( name ) {
if ( jQuery.isFunction( name ) ) {
return this.each(function(i) {
var self = jQuery(this);
self.removeAttr( name.call(this, i, self.attr(name)) );
});
}

return this.each(function(){
jQuery.attr( this, name, "" );
if ( this.nodeType === 1 ) {
this.removeAttribute( name );
}
});
},

addClass: function( value ) {
if ( jQuery.isFunction(value) ) {
return this.each(function() {
jQuery(this).addClass( value.call(this) );
return this.each(function(i) {
var self = jQuery(this);
self.addClass( value.call(this, i, self.attr("class")) );
});
}

Expand Down Expand Up @@ -46,8 +63,9 @@ jQuery.fn.extend({

removeClass: function( value ) {
if ( jQuery.isFunction(value) ) {
return this.each(function() {
jQuery(this).removeClass( value.call(this) );
return this.each(function(i) {
var self = jQuery(this);
self.removeClass( value.call(this, i, self.attr("class")) );
});
}

Expand Down Expand Up @@ -75,6 +93,40 @@ jQuery.fn.extend({
return this;
},

toggleClass: function( classNames, state ) {
var type = typeof classNames;

if ( jQuery.isFunction( classNames ) ) {
return this.each(function(i) {
var self = jQuery(this);
self.toggleClass( classNames.call(this, i, self.attr("class")), state );
});
}

return this.each(function(){
if ( type === "string" ) {
// toggle individual class names
var isBool = typeof state === "boolean", className, i = 0,
classNames = classNames.split( rspace );

while ( (className = classNames[ i++ ]) ) {
// check each className given, space seperated list
state = isBool ? state : !jQuery(this).hasClass( className );
jQuery(this)[ state ? "addClass" : "removeClass" ]( className );
}

} else if ( type === "undefined" || type === "boolean" ) {
if ( this.className ) {
// store className if set
jQuery.data( this, "__className__", this.className );
}

// toggle whole className
this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || "";
}
});
},

hasClass: function( selector ) {
var className = " " + selector + " ";
for ( var i = 0, l = this.length; i < l; i++ ) {
Expand Down Expand Up @@ -149,9 +201,11 @@ jQuery.fn.extend({

var val = value;

return this.each(function() {
return this.each(function(i) {
var self = jQuery(this);

if ( jQuery.isFunction(value) ) {
val = value.call(this);
val = value.call(this, i, self.val());

// Typecast each time if the value is a Function and the appended
// value is therefore different each time.
Expand All @@ -165,13 +219,13 @@ jQuery.fn.extend({
}

if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
this.checked = jQuery.inArray( jQuery(this).val(), val ) >= 0;
this.checked = jQuery.inArray( self.val(), val ) >= 0;

} else if ( jQuery.nodeName( this, "select" ) ) {
var values = jQuery.makeArray(val);

jQuery( "option", this ).each(function() {
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
this.selected = jQuery.inArray( self.val(), values ) >= 0;
});

if ( !values.length ) {
Expand All @@ -185,50 +239,6 @@ jQuery.fn.extend({
}
});

jQuery.each({
removeAttr: function( name ) {
jQuery.attr( this, name, "" );
if ( this.nodeType === 1 ) {
this.removeAttribute( name );
}
},

toggleClass: function( classNames, state ) {
var type = typeof classNames;

if ( type === "string" ) {
// toggle individual class names
var isBool = typeof state === "boolean", className, i = 0,
classNames = classNames.split( rspace );

while ( (className = classNames[ i++ ]) ) {
// check each className given, space seperated list
state = isBool ? state : !jQuery(this).hasClass( className );
jQuery(this)[ state ? "addClass" : "removeClass" ]( className );
}

} else if ( type === "undefined" || type === "boolean" ) {
if ( this.className ) {
// store className if set
jQuery.data( this, "__className__", this.className );
}

// toggle whole className
this.className = this.className || classNames === false ? "" : jQuery.data( this, "__className__" ) || "";
}
}
}, function( name, fn ) {
jQuery.fn[ name ] = function( val, state ) {
if ( jQuery.isFunction( val ) ) {
return this.each(function() {
jQuery(this)[ name ]( val.call(this), state );
});
}

return this.each( fn, arguments );
};
});

jQuery.extend({
attrFn: {
val: true,
Expand Down
2 changes: 1 addition & 1 deletion src/core.js
Expand Up @@ -775,7 +775,7 @@ function access( elems, key, value, exec, fn, pass ) {
exec = exec && jQuery.isFunction(value);

for ( var i = 0; i < length; i++ ) {
fn( elems[i], key, exec ? value.call( elems[i], i ) : value, pass );
fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
}

return elems;
Expand Down
16 changes: 9 additions & 7 deletions src/manipulation.js
Expand Up @@ -33,8 +33,9 @@ if ( !jQuery.support.htmlSerialize ) {
jQuery.fn.extend({
text: function( text ) {
if ( jQuery.isFunction(text) ) {
return this.each(function() {
return jQuery(this).text( text.call(this) );
return this.each(function(i) {
var self = jQuery(this);
return self.text( text.call(this, i, self.text()) );
});
}

Expand All @@ -47,8 +48,8 @@ jQuery.fn.extend({

wrapAll: function( html ) {
if ( jQuery.isFunction( html ) ) {
return this.each(function() {
jQuery(this).wrapAll( html.apply(this, arguments) );
return this.each(function(i) {
jQuery(this).wrapAll( html.call(this, i) );
});
}

Expand Down Expand Up @@ -228,9 +229,10 @@ jQuery.fn.extend({
var results, first, value = args[0], scripts = [];

if ( jQuery.isFunction(value) ) {
return this.each(function() {
args[0] = value.call(this);
return jQuery(this).domManip( args, table, callback );
return this.each(function(i) {
var self = jQuery(this);
args[0] = value.call(this, i, table ? self.html() : undefined);
return self.domManip( args, table, callback );
});
}

Expand Down

3 comments on commit 600d314

@paulirish
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, these are all the setter methods I noticed that take a function:
css, attr
val, html, text
appendTo, append, prependTo, prepend,
insertBefore, before, insertAfter, after, replaceAll, replaceWith
wrap, wrapAll, wrapInner
addClass, removeClass, toggleClass

@jeresig
Copy link
Member Author

@jeresig jeresig commented on 600d314 Jan 7, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And now offset as well.

Out of these the follow receive the previous value: css, attr, val, html, text, append, prepend, addClass, removeClass, toggleClass, and offset.

@jeresig
Copy link
Member Author

@jeresig jeresig commented on 600d314 Jan 7, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also appendTo, prependTo, insertBefore, insertAfter, and replaceAll do NOT take a function (well, they can, but it won't do as you would expect, heh).

Please sign in to comment.