aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Gołębiowski-Owczarek <m.goleb@gmail.com>2022-10-03 18:10:42 +0200
committerGitHub <noreply@github.com>2022-10-03 18:10:42 +0200
commit7eb0019640a5856c42b451551eb7f995d913eba9 (patch)
tree68b5e68e5bffcf8c16c01d0c3dc8c786d2743d47
parent25400750fb2e08b0a7e1a752a3ca0e9eaec16163 (diff)
downloadjquery-7eb0019640a5856c42b451551eb7f995d913eba9.tar.gz
jquery-7eb0019640a5856c42b451551eb7f995d913eba9.zip
CSS: Return `undefined` for whitespace-only CSS variable values (#5120)
The spec requires that CSS variable values are trimmed. In browsers that do this - mainly, Safari, but also Firefox if the value only has leading whitespace - we currently return undefined; in other browsers, we return an empty string as the logic to fall back to undefined happens before trimming. This commit adds another explicit callback to `undefined` to have it consistent across browsers. Also, more explicit comments about behaviors we need to work around in various browsers have been added. Closes gh-5120 Ref gh-5106
-rw-r--r--src/css/curCSS.js28
-rw-r--r--test/unit/css.js4
2 files changed, 27 insertions, 5 deletions
diff --git a/src/css/curCSS.js b/src/css/curCSS.js
index 25b4630a5..72c3db9f5 100644
--- a/src/css/curCSS.js
+++ b/src/css/curCSS.js
@@ -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 ) ) {
diff --git a/test/unit/css.js b/test/unit/css.js
index b692caac9..a7a501df1 100644
--- a/test/unit/css.js
+++ b/test/unit/css.js
@@ -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>"
@@ -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;
@@ -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 );
} );