Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
28 changes: 24 additions & 4 deletions src/css/curCSS.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,37 @@ function curCSS( elem, name, computed ) {

// getPropertyValue is needed for `.css('--customProperty')` (gh-3144)
if ( computed ) {
ret = computed.getPropertyValue( name ) || computed[ name ];

// trim whitespace for custom property (issue gh-4926)
if ( isCustomProp && ret !== undefined ) {
// Support: IE <=9 - 11+
// IE only supports `"float"` in `getPropertyValue`; in computed styles
// it's only available as `"cssFloat"`. We no longer modify properties
// sent to `.css()` apart from camelCasing, so we need to check both.
// Normally, this would create difference in behavior: if
// `getPropertyValue` returns an empty string, the value returned
// by `.css()` would be `undefined`. This is usually the case for
// disconnected elements. However, in IE even disconnected elements
// with no styles return `"none"` for `getPropertyValue( "float" )`
ret = computed.getPropertyValue( name ) || computed[ name ];

if ( isCustomProp && ret ) {

// Support: Firefox 105+, Chrome <=105+
// Spec requires trimming whitespace for custom properties (gh-4926).
// Firefox only trims leading whitespace. Chrome just collapses
// both leading & trailing whitespace to a single space.
//
// Fall back to `undefined` if empty string returned.
// This collapses a missing definition with property defined
// and set to an empty string but there's no standard API
// allowing us to differentiate them without a performance penalty
// and returning `undefined` aligns with older jQuery.
//
// rtrim treats U+000D CARRIAGE RETURN and U+000C FORM FEED
// as whitespace while CSS does not, but this is not a problem
// because CSS preprocessing replaces them with U+000A LINE FEED
// (which *is* CSS whitespace)
// https://www.w3.org/TR/css-syntax-3/#input-preprocessing
ret = ret.replace( rtrim, "$1" );
ret = ret.replace( rtrim, "$1" ) || undefined;
}

if ( ret === "" && !isAttached( elem ) ) {
Expand Down
4 changes: 3 additions & 1 deletion test/unit/css.js
Original file line number Diff line number Diff line change
Expand Up @@ -1748,6 +1748,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
" --prop10:\f\r\n\t val10 \f\r\n\t;\n" +
" --prop11:\u000C\u000D\u000A\u0009\u0020val11\u0020\u0009\u000A\u000D\u000C;\n" +
" --prop12:\u000Bval12\u000B;\n" +
" --space: ;\n" +
" --empty:;\n" +
" }\n" +
"</style>"
Expand All @@ -1757,7 +1758,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
$elem = jQuery( "<div>" ).addClass( "test__customProperties" )
.appendTo( "#qunit-fixture" ),
webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ),
expected = 19;
expected = 20;

if ( webkitOrBlink ) {
expected -= 2;
Expand Down Expand Up @@ -1803,6 +1804,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) {
assert.equal( $elem.css( "--prop10" ), "val10", "Multiple preceding and following escaped unicode whitespace trimmed" );
assert.equal( $elem.css( "--prop11" ), "val11", "Multiple preceding and following unicode whitespace trimmed" );
assert.equal( $elem.css( "--prop12" ), "\u000Bval12\u000B", "Multiple preceding and following non-CSS whitespace reserved" );
assert.equal( $elem.css( "--space" ), undefined );
assert.equal( $elem.css( "--empty" ), undefined );
assert.equal( $elem.css( "--nonexistent" ), undefined );
} );
Expand Down