mirror of
https://github.com/jquery/jquery.git
synced 2026-02-01 04:05:03 -05:00
CSS: Don't cache unrecognized CSS property names
This prevents jQuery from caching a prefixed property name if provided directly by the user, e.g. the following code: elem.css( "msTransform", "translate(5px, 2px)" ); should not prevent one from from later setting the transition directly: elem.css( "transform", "translate(5px, 2px)" ); on a browser not understanding the unprefixed version which is the case for Safari 8 & transform. Fixes gh-2015 Closes gh-2298
This commit is contained in:
21
src/css.js
21
src/css.js
@@ -3,6 +3,7 @@ define([
|
||||
"./var/pnum",
|
||||
"./core/access",
|
||||
"./css/var/rmargin",
|
||||
"./var/document",
|
||||
"./var/rcssNum",
|
||||
"./css/var/rnumnonpx",
|
||||
"./css/var/cssExpand",
|
||||
@@ -18,8 +19,8 @@ define([
|
||||
"./core/init",
|
||||
"./core/ready",
|
||||
"./selector" // contains
|
||||
], function( jQuery, pnum, access, rmargin, rcssNum, rnumnonpx, cssExpand, isHidden,
|
||||
getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, showHide ) {
|
||||
], function( jQuery, pnum, access, rmargin, document, rcssNum, rnumnonpx, cssExpand,
|
||||
isHidden, getStyles, swap, curCSS, adjustCSS, addGetHookIf, support, showHide ) {
|
||||
|
||||
var
|
||||
// Swappable if display is none or starts with table
|
||||
@@ -34,29 +35,27 @@ var
|
||||
fontWeight: "400"
|
||||
},
|
||||
|
||||
cssPrefixes = [ "Webkit", "Moz", "ms" ];
|
||||
cssPrefixes = [ "Webkit", "Moz", "ms" ],
|
||||
emptyStyle = document.createElement( "div" ).style;
|
||||
|
||||
// Return a css property mapped to a potentially vendor prefixed property
|
||||
function vendorPropName( style, name ) {
|
||||
function vendorPropName( name ) {
|
||||
|
||||
// Shortcut for names that are not vendor prefixed
|
||||
if ( name in style ) {
|
||||
if ( name in emptyStyle ) {
|
||||
return name;
|
||||
}
|
||||
|
||||
// Check for vendor prefixed names
|
||||
var capName = name[0].toUpperCase() + name.slice(1),
|
||||
origName = name,
|
||||
i = cssPrefixes.length;
|
||||
|
||||
while ( i-- ) {
|
||||
name = cssPrefixes[ i ] + capName;
|
||||
if ( name in style ) {
|
||||
if ( name in emptyStyle ) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return origName;
|
||||
}
|
||||
|
||||
function setPositiveNumber( elem, value, subtract ) {
|
||||
@@ -203,7 +202,7 @@ jQuery.extend({
|
||||
style = elem.style;
|
||||
|
||||
name = jQuery.cssProps[ origName ] ||
|
||||
( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
|
||||
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
|
||||
|
||||
// Gets hook for the prefixed version, then unprefixed version
|
||||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||||
@@ -261,7 +260,7 @@ jQuery.extend({
|
||||
|
||||
// Make sure that we're working with the right name
|
||||
name = jQuery.cssProps[ origName ] ||
|
||||
( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
|
||||
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
|
||||
|
||||
// Try prefixed name followed by the unprefixed name
|
||||
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
|
||||
|
||||
@@ -1116,4 +1116,84 @@ test( "Do not throw on frame elements from css method (#15098)", 1, function() {
|
||||
ok( false, "It did throw" );
|
||||
}
|
||||
});
|
||||
|
||||
( function() {
|
||||
var vendorPrefixes = [ "Webkit", "Moz", "ms" ];
|
||||
|
||||
function resetCssPropsFor( name ) {
|
||||
delete jQuery.cssProps[ name ];
|
||||
jQuery.each( vendorPrefixes, function( index, prefix ) {
|
||||
delete jQuery.cssProps[ prefix + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
|
||||
} );
|
||||
}
|
||||
|
||||
test( "Don't default to a cached previously used wrong prefixed name (gh-2015)", function() {
|
||||
// Note: this test needs a property we know is only supported in a prefixed version
|
||||
// by at least one of our main supported browsers. This may get out of date so let's
|
||||
// use -(webkit|moz)-appearance as well as those two are not on a standards track.
|
||||
var appearanceName, transformName, elem, elemStyle,
|
||||
transformVal = "translate(5px, 2px)",
|
||||
emptyStyle = document.createElement( "div" ).style;
|
||||
|
||||
if ( "appearance" in emptyStyle ) {
|
||||
appearanceName = "appearance";
|
||||
} else {
|
||||
jQuery.each( vendorPrefixes, function( index, prefix ) {
|
||||
var prefixedProp = prefix + "Appearance";
|
||||
if ( prefixedProp in emptyStyle ) {
|
||||
appearanceName = prefixedProp;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
if ( "transform" in emptyStyle ) {
|
||||
transformName = "transform";
|
||||
} else {
|
||||
jQuery.each( vendorPrefixes, function( index, prefix ) {
|
||||
var prefixedProp = prefix + "Transform";
|
||||
if ( prefixedProp in emptyStyle ) {
|
||||
transformName = prefixedProp;
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
expect( !!appearanceName + !!transformName + 1 );
|
||||
|
||||
resetCssPropsFor( "appearance" );
|
||||
resetCssPropsFor( "transform" );
|
||||
|
||||
elem = jQuery( "<div/>" )
|
||||
.css( {
|
||||
msAppearance: "none",
|
||||
appearance: "none",
|
||||
|
||||
// Only the ms prefix is used to make sure we haven't e.g. set
|
||||
// webkitTransform ourselves in the test.
|
||||
msTransform: transformVal,
|
||||
transform: transformVal
|
||||
} );
|
||||
elemStyle = elem[ 0 ].style;
|
||||
|
||||
if ( appearanceName ) {
|
||||
equal( elemStyle[ appearanceName ], "none", "setting properly-prefixed appearance" );
|
||||
}
|
||||
if ( transformName ) {
|
||||
equal( elemStyle[ transformName ], transformVal, "setting properly-prefixed transform" );
|
||||
}
|
||||
equal( elemStyle.undefined, undefined, "Nothing writes to node.style.undefined" );
|
||||
} );
|
||||
|
||||
test( "Don't detect fake set properties on a node when caching the prefixed version", function() {
|
||||
expect( 1 );
|
||||
|
||||
var elem = jQuery( "<div/>" ),
|
||||
style = elem[ 0 ].style;
|
||||
style.MozFakeProperty = "old value";
|
||||
elem.css( "fakeProperty", "new value" );
|
||||
|
||||
equal( style.MozFakeProperty, "old value", "Fake prefixed property is not cached" );
|
||||
} );
|
||||
|
||||
} )();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user