From 04d7e47aeddf48e9ee84ace3a5798c147a0ac70f Mon Sep 17 00:00:00 2001 From: fecore1 Date: Tue, 14 Sep 2021 01:17:15 +0800 Subject: [PATCH 1/5] CSS: workaround trim whitespace #4926 --- src/css/curCSS.js | 5 ++++- test/unit/css.js | 16 +++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 59a639f688..5e90ca4aff 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -9,7 +9,10 @@ function curCSS( elem, name, computed ) { // getPropertyValue is needed for `.css('--customProperty')` (gh-3144) if ( computed ) { - ret = computed.getPropertyValue( name ) || computed[ name ]; + ret = computed.getPropertyValue( name ); + + // trim whitespace (issue #4926) + ret = ( ret && ret.trim() ) || computed[ name ]; if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); diff --git a/test/unit/css.js b/test/unit/css.js index 8ade482ffa..2257a89c4e 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1739,8 +1739,9 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { " --prop1:val1;\n" + " --prop2: val2;\n" + " --prop3:val3 ;\n" + - " --prop4:\"val4\";\n" + - " --prop5:'val5';\n" + + " --prop4: val4 ;\n" + + " --prop5:\"val5\";\n" + + " --prop6:'val6';\n" + " }\n" + "" ); @@ -1749,7 +1750,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { $elem = jQuery( "
" ).addClass( "test__customProperties" ) .appendTo( "#qunit-fixture" ), webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ), - expected = 10; + expected = 11; if ( webkitOrBlink ) { expected -= 2; @@ -1777,15 +1778,16 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { assert.equal( $elem.css( "--prop1" ), "val1", "Basic CSS custom property" ); - assert.equal( $elem.css( "--prop2" ), " val2", "Preceding whitespace maintained" ); - assert.equal( $elem.css( "--prop3" ), "val3 ", "Following whitespace maintained" ); + assert.equal( $elem.css( "--prop2" ), "val2", "Preceding whitespace trimmed" ); + assert.equal( $elem.css( "--prop3" ), "val3", "Following whitespace trimmed" ); + assert.equal( $elem.css( "--prop4" ), "val4", "Preceding and Following whitespace trimmed" ); // Support: Chrome <=49 - 73+, Safari <=9.1 - 12.1+ // Chrome treats single quotes as double ones. // Safari treats double quotes as single ones. if ( !webkitOrBlink ) { - assert.equal( $elem.css( "--prop4" ), "\"val4\"", "Works with double quotes" ); - assert.equal( $elem.css( "--prop5" ), "'val5'", "Works with single quotes" ); + assert.equal( $elem.css( "--prop5" ), "\"val5\"", "Works with double quotes" ); + assert.equal( $elem.css( "--prop6" ), "'val6'", "Works with single quotes" ); } } ); From b6a958e91519eda18ebde889111ca8f6a4e14ba6 Mon Sep 17 00:00:00 2001 From: fecore1 Date: Tue, 14 Sep 2021 10:16:03 +0800 Subject: [PATCH 2/5] CSS: add limit to trim whitespace only for custom prop --- src/css.js | 2 +- src/css/curCSS.js | 12 ++++++++---- src/css/var/rcustomProp.js | 1 + 3 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 src/css/var/rcustomProp.js diff --git a/src/css.js b/src/css.js index c82a08c545..b50aa3d91a 100644 --- a/src/css.js +++ b/src/css.js @@ -4,6 +4,7 @@ import nodeName from "./core/nodeName.js"; import rcssNum from "./var/rcssNum.js"; import isIE from "./var/isIE.js"; import rnumnonpx from "./css/var/rnumnonpx.js"; +import rcustomProp from "./css/var/rcustomProp.js"; import cssExpand from "./css/var/cssExpand.js"; import isAutoPx from "./css/isAutoPx.js"; import cssCamelCase from "./css/cssCamelCase.js"; @@ -24,7 +25,6 @@ var // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, - rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 5e90ca4aff..1f351839e3 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -1,18 +1,22 @@ import jQuery from "../core.js"; import isAttached from "../core/isAttached.js"; import getStyles from "./var/getStyles.js"; +import rcustomProp from "./var/rcustomProp.js"; function curCSS( elem, name, computed ) { - var ret; + var ret, + isCustomProp = rcustomProp.test( name ); computed = computed || getStyles( elem ); // getPropertyValue is needed for `.css('--customProperty')` (gh-3144) if ( computed ) { - ret = computed.getPropertyValue( name ); + ret = computed.getPropertyValue( name ) || computed[ name ]; - // trim whitespace (issue #4926) - ret = ( ret && ret.trim() ) || computed[ name ]; + // trim whitespace for custom property (issue #4926) + if ( isCustomProp ) { + ret = ret.trim(); + } if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); diff --git a/src/css/var/rcustomProp.js b/src/css/var/rcustomProp.js new file mode 100644 index 0000000000..f435e7cd7b --- /dev/null +++ b/src/css/var/rcustomProp.js @@ -0,0 +1 @@ +export default ( /^--/ ); From af5f56e5a14921f383abfda2e2c1c929553ddd6a Mon Sep 17 00:00:00 2001 From: fecore1 Date: Fri, 17 Sep 2021 10:21:30 +0800 Subject: [PATCH 3/5] Tests: add test case to css custom property [jquery#4926](https://github.com/jquery/jquery/issues/4926) --- test/unit/css.js | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/test/unit/css.js b/test/unit/css.js index 2257a89c4e..039b6653a6 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1738,10 +1738,13 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { " .test__customProperties {\n" + " --prop1:val1;\n" + " --prop2: val2;\n" + - " --prop3:val3 ;\n" + - " --prop4: val4 ;\n" + - " --prop5:\"val5\";\n" + - " --prop6:'val6';\n" + + " --prop3: val3;\n" + + " --prop4:val4 ;\n" + + " --prop5:val5 ;\n" + + " --prop6: val6 ;\n" + + " --prop7: val7 ;\n" + + " --prop8:\"val8\";\n" + + " --prop9:'val9';\n" + " }\n" + "" ); @@ -1750,7 +1753,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { $elem = jQuery( "
" ).addClass( "test__customProperties" ) .appendTo( "#qunit-fixture" ), webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ), - expected = 11; + expected = 14; if ( webkitOrBlink ) { expected -= 2; @@ -1779,15 +1782,18 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { assert.equal( $elem.css( "--prop1" ), "val1", "Basic CSS custom property" ); assert.equal( $elem.css( "--prop2" ), "val2", "Preceding whitespace trimmed" ); - assert.equal( $elem.css( "--prop3" ), "val3", "Following whitespace trimmed" ); - assert.equal( $elem.css( "--prop4" ), "val4", "Preceding and Following whitespace trimmed" ); + assert.equal( $elem.css( "--prop3" ), "val3", "Multiple preceding whitespace trimmed" ); + assert.equal( $elem.css( "--prop4" ), "val4", "Following whitespace trimmed" ); + assert.equal( $elem.css( "--prop5" ), "val5", "Multiple Following whitespace trimmed" ); + assert.equal( $elem.css( "--prop6" ), "val6", "Preceding and Following whitespace trimmed" ); + assert.equal( $elem.css( "--prop7" ), "val7", "Multiple preceding and following whitespace trimmed" ); // Support: Chrome <=49 - 73+, Safari <=9.1 - 12.1+ // Chrome treats single quotes as double ones. // Safari treats double quotes as single ones. if ( !webkitOrBlink ) { - assert.equal( $elem.css( "--prop5" ), "\"val5\"", "Works with double quotes" ); - assert.equal( $elem.css( "--prop6" ), "'val6'", "Works with single quotes" ); + assert.equal( $elem.css( "--prop8" ), "\"val8\"", "Works with double quotes" ); + assert.equal( $elem.css( "--prop9" ), "'val9'", "Works with single quotes" ); } } ); From 29384e672101682632b50c60fe7388abc75af7fb Mon Sep 17 00:00:00 2001 From: fecore1 Date: Thu, 23 Sep 2021 14:49:31 +0800 Subject: [PATCH 4/5] CSS: just trim css whitespace https://www.w3.org/TR/css-syntax-3/#whitespace --- src/css/curCSS.js | 3 ++- src/selector.js | 4 ++-- src/selector/rbuggyQSA.js | 2 +- src/var/rtrim.js | 6 ++++++ src/{selector => }/var/whitespace.js | 0 test/unit/css.js | 9 ++++++++- 6 files changed, 19 insertions(+), 5 deletions(-) create mode 100644 src/var/rtrim.js rename src/{selector => }/var/whitespace.js (100%) diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 1f351839e3..6a0c2ef1ca 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -2,6 +2,7 @@ import jQuery from "../core.js"; import isAttached from "../core/isAttached.js"; import getStyles from "./var/getStyles.js"; import rcustomProp from "./var/rcustomProp.js"; +import rtrim from "../var/rtrim.js"; function curCSS( elem, name, computed ) { var ret, @@ -15,7 +16,7 @@ function curCSS( elem, name, computed ) { // trim whitespace for custom property (issue #4926) if ( isCustomProp ) { - ret = ret.trim(); + ret = ret.replace( rtrim, "$1" ); } if ( ret === "" && !isAttached( elem ) ) { diff --git a/src/selector.js b/src/selector.js index f7e8d9b607..4b9c8b6ed7 100644 --- a/src/selector.js +++ b/src/selector.js @@ -5,8 +5,9 @@ import documentElement from "./var/documentElement.js"; import indexOf from "./var/indexOf.js"; import pop from "./var/pop.js"; import push from "./var/push.js"; -import whitespace from "./selector/var/whitespace.js"; +import whitespace from "./var/whitespace.js"; import rbuggyQSA from "./selector/rbuggyQSA.js"; +import rtrim from "./var/rtrim.js"; import isIE from "./var/isIE.js"; // The following utils are attached directly to the jQuery object. @@ -71,7 +72,6 @@ var i, // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + diff --git a/src/selector/rbuggyQSA.js b/src/selector/rbuggyQSA.js index 7a62107332..bae05398fd 100644 --- a/src/selector/rbuggyQSA.js +++ b/src/selector/rbuggyQSA.js @@ -1,5 +1,5 @@ import isIE from "../var/isIE.js"; -import whitespace from "./var/whitespace.js"; +import whitespace from "../var/whitespace.js"; var rbuggyQSA = isIE && new RegExp( diff --git a/src/var/rtrim.js b/src/var/rtrim.js new file mode 100644 index 0000000000..89d86d17a3 --- /dev/null +++ b/src/var/rtrim.js @@ -0,0 +1,6 @@ +import whitespace from "./whitespace.js"; + +export default new RegExp( + "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", + "g" +); diff --git a/src/selector/var/whitespace.js b/src/var/whitespace.js similarity index 100% rename from src/selector/var/whitespace.js rename to src/var/whitespace.js diff --git a/test/unit/css.js b/test/unit/css.js index 039b6653a6..100b8c8c5d 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -1745,6 +1745,9 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { " --prop7: val7 ;\n" + " --prop8:\"val8\";\n" + " --prop9:'val9';\n" + + " --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" + " }\n" + "" ); @@ -1753,7 +1756,7 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { $elem = jQuery( "
" ).addClass( "test__customProperties" ) .appendTo( "#qunit-fixture" ), webkitOrBlink = /\bsafari\b/i.test( navigator.userAgent ), - expected = 14; + expected = 17; if ( webkitOrBlink ) { expected -= 2; @@ -1795,6 +1798,10 @@ QUnit.testUnlessIE( "css(--customProperty)", function( assert ) { assert.equal( $elem.css( "--prop8" ), "\"val8\"", "Works with double quotes" ); assert.equal( $elem.css( "--prop9" ), "'val9'", "Works with single quotes" ); } + + 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" ); } ); // IE doesn't support CSS variables. From b42af36db484486a33ad279c9ff73013bed781a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Thu, 23 Sep 2021 13:25:08 +0200 Subject: [PATCH 5/5] Update src/css/curCSS.js --- src/css/curCSS.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/curCSS.js b/src/css/curCSS.js index 6a0c2ef1ca..6d8b6a2d3b 100644 --- a/src/css/curCSS.js +++ b/src/css/curCSS.js @@ -14,7 +14,7 @@ function curCSS( elem, name, computed ) { if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; - // trim whitespace for custom property (issue #4926) + // trim whitespace for custom property (issue gh-4926) if ( isCustomProp ) { ret = ret.replace( rtrim, "$1" ); }