CSS: Avoid filling jQuery.cssProps

Fixes gh-3986
Closes gh-4005

Avoids filling jQuery.cssProps by introducing a second internal
prop cache. This allows jQuery Migrate to detect external usage.
This commit is contained in:
Dave Methvin 2018-02-24 17:17:24 -05:00
parent b95e0da68e
commit 2b5f5d5e90
3 changed files with 48 additions and 39 deletions

View File

@ -13,12 +13,13 @@ define( [
"./css/adjustCSS", "./css/adjustCSS",
"./css/addGetHookIf", "./css/addGetHookIf",
"./css/support", "./css/support",
"./css/finalPropName",
"./core/init", "./core/init",
"./core/ready", "./core/ready",
"./selector" // contains "./selector" // contains
], function( jQuery, pnum, access, camelCase, document, rcssNum, rnumnonpx, cssExpand, ], function( jQuery, pnum, access, camelCase, document, rcssNum, rnumnonpx, cssExpand,
getStyles, swap, curCSS, adjustCSS, addGetHookIf, support ) { getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, finalPropName ) {
"use strict"; "use strict";
@ -33,40 +34,7 @@ var
cssNormalTransform = { cssNormalTransform = {
letterSpacing: "0", letterSpacing: "0",
fontWeight: "400" fontWeight: "400"
}, };
cssPrefixes = [ "Webkit", "Moz", "ms" ],
emptyStyle = document.createElement( "div" ).style;
// Return a css property mapped to a potentially vendor prefixed property
function vendorPropName( name ) {
// Shortcut for names that are not vendor prefixed
if ( name in emptyStyle ) {
return name;
}
// Check for vendor prefixed names
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
i = cssPrefixes.length;
while ( i-- ) {
name = cssPrefixes[ i ] + capName;
if ( name in emptyStyle ) {
return name;
}
}
}
// Return a property mapped along what jQuery.cssProps suggests or to
// a vendor prefixed property.
function finalPropName( name ) {
var ret = jQuery.cssProps[ name ];
if ( !ret ) {
ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
}
return ret;
}
function setPositiveNumber( elem, value, subtract ) { function setPositiveNumber( elem, value, subtract ) {

39
src/css/finalPropName.js Normal file
View File

@ -0,0 +1,39 @@
define( [ "../var/document" ], function( document ) {
"use strict";
var cssPrefixes = [ "Webkit", "Moz", "ms" ],
emptyStyle = document.createElement( "div" ).style,
vendorProps = {};
// Return a vendor-prefixed property or undefined
function vendorPropName( name ) {
// Check for vendor prefixed names
var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
i = cssPrefixes.length;
while ( i-- ) {
name = cssPrefixes[ i ] + capName;
if ( name in emptyStyle ) {
return name;
}
}
}
// Return a potentially-mapped jQuery.cssProps or vendor prefixed property
function finalPropName( name ) {
var final = jQuery.cssProps[ name ] || vendorProps[ name ];
if ( final ) {
return final;
}
if ( name in emptyStyle ) {
return name;
}
return vendorProps[ name ] = vendorPropName( name ) || name;
}
return finalPropName;
} );

View File

@ -1,7 +1,9 @@
define( [ define( [
"../core", "../core",
"../css/finalPropName",
"../css" "../css"
], function( jQuery ) { ], function( jQuery, finalPropName ) {
"use strict"; "use strict";
@ -84,9 +86,9 @@ Tween.propHooks = {
// Use .style if available and use plain properties where available. // Use .style if available and use plain properties where available.
if ( jQuery.fx.step[ tween.prop ] ) { if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween ); jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.nodeType === 1 && } else if ( tween.elem.nodeType === 1 && (
( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ||
jQuery.cssHooks[ tween.prop ] ) ) { tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
} else { } else {
tween.elem[ tween.prop ] = tween.now; tween.elem[ tween.prop ] = tween.now;