Skip to content

Commit 808bf5c

Browse files
committed
Attributes: Warn and fill .toggleClass( boolean )
Fixes #175 Closes #181
1 parent e89016a commit 808bf5c

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

src/attributes.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
var oldRemoveAttr = jQuery.fn.removeAttr,
3+
oldToggleClass = jQuery.fn.toggleClass,
34
rmatchNonSpace = /\S+/g;
45

56
jQuery.fn.removeAttr = function( name ) {
@@ -14,3 +15,34 @@ jQuery.fn.removeAttr = function( name ) {
1415

1516
return oldRemoveAttr.apply( this, arguments );
1617
};
18+
19+
jQuery.fn.toggleClass = function( state ) {
20+
21+
// Only deprecating no-args or single boolean arg
22+
if ( state !== undefined && typeof state !== "boolean" ) {
23+
return oldToggleClass.apply( this, arguments );
24+
}
25+
26+
migrateWarn( "jQuery.fn.toggleClass( boolean ) is deprecated" );
27+
28+
// Toggle entire class name of each element
29+
return this.each( function() {
30+
var className = this.getAttribute && this.getAttribute( "class" ) || "";
31+
32+
if ( className ) {
33+
jQuery.data( this, "__className__", className );
34+
}
35+
36+
// If the element has a class name or if we're passed `false`,
37+
// then remove the whole classname (if there was one, the above saved it).
38+
// Otherwise bring back whatever was previously saved (if anything),
39+
// falling back to the empty string if nothing was stored.
40+
if ( this.setAttribute ) {
41+
this.setAttribute( "class",
42+
className || state === false ?
43+
"" :
44+
jQuery.data( this, "__className__" ) || ""
45+
);
46+
}
47+
} );
48+
};

test/attributes.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,47 @@ QUnit.test( ".removeAttr( boolean attribute )", function( assert ) {
4141
} );
4242

4343
} );
44+
45+
QUnit.test( ".toggleClass( boolean )", function( assert ) {
46+
assert.expect( 14 );
47+
48+
var e = jQuery( "<div />" ).appendTo( "#qunit-fixture" );
49+
50+
expectWarning( "toggling initially empty class", function() {
51+
e.toggleClass( true );
52+
assert.equal( e[ 0 ].className, "", "Assert class is empty (data was empty)" );
53+
} );
54+
55+
expectNoWarning( ".toggleClass( string ) not full className", function() {
56+
e.attr( "class", "" );
57+
e.toggleClass( "classy" );
58+
assert.equal( e.attr( "class" ), "classy", "class was toggle-set" );
59+
e.toggleClass( "classy", false );
60+
assert.equal( e.attr( "class" ), "", "class was toggle-removed" );
61+
} );
62+
63+
expectWarning( ".toggleClass() save and clear", 1, function() {
64+
e.addClass( "testD testE" );
65+
assert.ok( e.is( ".testD.testE" ), "Assert class present" );
66+
e.toggleClass();
67+
assert.ok( !e.is( ".testD.testE" ), "Assert class not present" );
68+
69+
// N.B.: Store should have "testD testE" now, next test will assert that
70+
} );
71+
72+
expectWarning( ".toggleClass() restore", 1, function() {
73+
e.toggleClass();
74+
assert.ok( e.is( ".testD.testE" ), "Assert class present (restored from data)" );
75+
} );
76+
77+
expectWarning( ".toggleClass( boolean )", 1, function() {
78+
e.toggleClass( false );
79+
assert.ok( !e.is( ".testD.testE" ), "Assert class not present" );
80+
e.toggleClass( true );
81+
assert.ok( e.is( ".testD.testE" ), "Assert class present (restored from data)" );
82+
e.toggleClass();
83+
e.toggleClass( false );
84+
e.toggleClass();
85+
assert.ok( e.is( ".testD.testE" ), "Assert class present (restored from data)" );
86+
} );
87+
} );

warnings.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,9 @@ See jQuery-ui [commit](https://github.com/jquery/jquery-ui/commit/c0093b599fcd58
166166
**Cause:** The standard way to add new custom selectors through jQuery is `jQuery.expr.pseudos`. These two other aliases are deprecated, although they still work as of jQuery 3.0.
167167

168168
**Solution:** Rename any of the older usage to `jQuery.expr.pseudos`. The functionality is identical.
169+
170+
### JQMIGRATE: jQuery.fn.toggleClass( [ boolean ] ) is deprecated
171+
172+
**Cause:** Calling `.toggleClass()` with no arguments, or with a single Boolean `true` or `false` argument, has been deprecated. Its behavior was poorly documented, but essentially the method saved away the current `class` value in a data item when the class was removed and restored the saved value when it was toggled back. If you do not believe you are specificially trying to use this form of the method, it is possible you are accidentally doing so via an inadvertent undefined value, as `.toggleClass( undefined )` toggles all classes.
173+
174+
**Solution:** If this functionality is still needed, save the current full `.attr( "class" )` value in a data item and restore it when required.

0 commit comments

Comments
 (0)