Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fixup! CSS: Warn and fill jQuery.cssNumber and .css(name, Number)
  • Loading branch information
mgol committed Apr 11, 2020
commit ee8f83f98eedf9944fd6f026f6af04907e2f96eb
51 changes: 47 additions & 4 deletions src/css.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@

var internalSwapCall = false;
var internalSwapCall = false,
ralphaStart = /^[a-z]/,

// The regex visualized:
//
// /----------\
// | | /-------\
// | / Top \ | | |
// /--- Border ---+-| Right |-+---+- Width -+---\
// | | Bottom | |
// | \ Left / |
// | |
// | /----------\ |
// | /-------------\ | | |- END
// | | | | / Top \ | |
// | | / Margin \ | | | Right | | |
// |---------+-| |-+---+-| Bottom |-+----|
// | \ Padding / \ Left / |
// BEGIN -| |
// | /---------\ |
// | | | |
// | | / Min \ | / Width \ |
// \--------------+-| |-+---| |---/
// \ Max / \ Height /
rautoPx = /^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;

function camelCaseString( string ) {
return string.replace( /-([a-z])/g, function( _, letter ) {
return letter.toUpperCase();
} );
}

// If this version of jQuery has .swap(), don't false-alarm on internal uses
if ( jQuery.swap ) {
Expand Down Expand Up @@ -56,8 +86,21 @@ if ( jQueryVersionSince( "3.4.0" ) && typeof Proxy !== "undefined" ) {
if ( !jQuery.cssNumber ) {
jQuery.cssNumber = {};
}
migrateWarnProp( jQuery, "cssNumber", jQuery.cssNumber,
"jQuery.cssNumber is deprecated" );

// jQuery 3.x uses jQuery.cssNumber internally so we can't warn on access there.
if ( jQueryVersionSince( "4.0.0" ) ) {
migrateWarnProp( jQuery, "cssNumber", jQuery.cssNumber,
"jQuery.cssNumber is deprecated" );
}

function isAutoPx( prop ) {

// The first test is used to ensure that:
// 1. The prop starts with a lowercase letter (as we uppercase it for the second regex).
// 2. The prop is not empty.
return ralphaStart.test( prop ) &&
rautoPx.test( prop[ 0 ].toUpperCase() + prop.slice( 1 ) );
}

var oldFnCss = jQuery.fn.css;

Expand All @@ -68,7 +111,7 @@ jQuery.fn.css = function( name, value ) {
jQuery.fn.css.call( origThis, n, v );
} );
}
if ( typeof value === "number" ) {
if ( typeof value === "number" && !isAutoPx( camelCaseString( name ) ) ) {
migrateWarn( "Use of number-typed values is deprecated in jQuery.fn.css" );
}

Expand Down
69 changes: 58 additions & 11 deletions test/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,44 +42,91 @@ QUnit[ ( jQueryVersionSince( "3.4.0" ) && typeof Proxy !== "undefined" ) ? "test
delete jQuery.cssProps.devoHat;
} );

QUnit.test( "jQuery.css with numbers", function( assert) {
assert.expect( 4 );
QUnit.test( "jQuery.css with numbers", function( assert ) {
assert.expect( 5 );

var whitelist = [
"margin",
"marginTop",
"marginRight",
"marginBottom",
"marginLeft",
"padding",
"paddingTop",
"paddingRight",
"paddingBottom",
"paddingLeft",
"top",
"right",
"bottom",
"left",
"width",
"height",
"minWidth",
"minHeight",
"maxWidth",
"maxHeight",
"border",
"borderWidth",
"borderTop",
"borderTopWidth",
"borderRight",
"borderRightWidth",
"borderBottom",
"borderBottomWidth",
"borderLeft",
"borderLeftWidth"
];

function kebabCase( string ) {
return string.replace( /[A-Z]/g, function( match ) {
return "-" + match.toLowerCase();
} );
}

expectWarning( assert, "Number value direct", 1, function() {
jQuery( "<div />" ).css( "height", 10 );
expectWarning( assert, "Number value direct", function() {
jQuery( "<div />" ).css( "line-height", 10 );
} );

expectWarning( assert, "Number in an object", 2, function() {
expectWarning( assert, "Number in an object", 1, function() {
jQuery( "<div />" ).css( {
"width": 14,
"height": "10px",
"line-height": 2
} );
} );

expectNoWarning( assert, "Number value direct", function() {
jQuery( "<div />" ).css( "height", 10 );
expectNoWarning( assert, "String value direct", function() {
jQuery( "<div />" ).css( "line-height", "10px" );
} );

expectNoWarning( assert, "Number in an object", function() {
expectNoWarning( assert, "String in an object", function() {
jQuery( "<div />" ).css( {
"width": "14em",
"height": "10px",
"line-height": "2"
} );
} );

expectNoWarning( assert, "Number value (whitelisted props)", function() {
whitelist.forEach( function( prop ) {
jQuery( "<div />" ).css( prop, 1 );
jQuery( "<div />" ).css( kebabCase( prop ), 1 );
} );
} );

} );

QUnit.test( "jQuery.cssNumber", function( assert) {
assert.expect( 2 );
QUnit[ jQueryVersionSince( "4.0.0" ) ? "test" : "skip" ]( "jQuery.cssNumber",
function( assert ) {
assert.expect( 3 );

expectWarning( assert, "Setting cssNumber value", 1, function() {
jQuery.cssNumber.blart = true;
} );


expectWarning( assert, "Getting cssNumber value", function() {
expectWarning( assert, "Getting cssNumber value", 1, function() {
assert.ok( jQuery.cssNumber.blart, "blart was set" );
} );

Expand Down