🌐 AI搜索 & 代理 主页
Skip to content

Commit 619bf98

Browse files
ConnorAthertonmgol
authored andcommitted
CSS: Support custom properties
Fixes gh-3144 Closes gh-3199 Closes gh-3557
1 parent be041e4 commit 619bf98

File tree

3 files changed

+99
-9
lines changed

3 files changed

+99
-9
lines changed

src/css.js

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var
2828
// except "table", "table-cell", or "table-caption"
2929
// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
3030
rdisplayswap = /^(none|table(?!-c[ea]).+)/,
31+
rcustomProp = /^--/,
3132
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
3233
cssNormalTransform = {
3334
letterSpacing: "0",
@@ -57,6 +58,16 @@ function vendorPropName( name ) {
5758
}
5859
}
5960

61+
// Return a property mapped along what jQuery.cssProps suggests or to
62+
// a vendor prefixed property.
63+
function finalPropName( name ) {
64+
var ret = jQuery.cssProps[ name ];
65+
if ( !ret ) {
66+
ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
67+
}
68+
return ret;
69+
}
70+
6071
function setPositiveNumber( elem, value, subtract ) {
6172

6273
// Any relative (+/-) values have already been
@@ -218,10 +229,15 @@ jQuery.extend( {
218229
// Make sure that we're working with the right name
219230
var ret, type, hooks,
220231
origName = jQuery.camelCase( name ),
232+
isCustomProp = rcustomProp.test( name ),
221233
style = elem.style;
222234

223-
name = jQuery.cssProps[ origName ] ||
224-
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
235+
// Make sure that we're working with the right name. We don't
236+
// want to query the value if it is a CSS custom property
237+
// since they are user-defined.
238+
if ( !isCustomProp ) {
239+
name = finalPropName( origName );
240+
}
225241

226242
// Gets hook for the prefixed version, then unprefixed version
227243
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
@@ -257,7 +273,11 @@ jQuery.extend( {
257273
if ( !hooks || !( "set" in hooks ) ||
258274
( value = hooks.set( elem, value, extra ) ) !== undefined ) {
259275

260-
style[ name ] = value;
276+
if ( isCustomProp ) {
277+
style.setProperty( name, value );
278+
} else {
279+
style[ name ] = value;
280+
}
261281
}
262282

263283
} else {
@@ -276,11 +296,15 @@ jQuery.extend( {
276296

277297
css: function( elem, name, extra, styles ) {
278298
var val, num, hooks,
279-
origName = jQuery.camelCase( name );
299+
origName = jQuery.camelCase( name ),
300+
isCustomProp = rcustomProp.test( name );
280301

281-
// Make sure that we're working with the right name
282-
name = jQuery.cssProps[ origName ] ||
283-
( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );
302+
// Make sure that we're working with the right name. We don't
303+
// want to modify the value if it is a CSS custom property
304+
// since they are user-defined.
305+
if ( !isCustomProp ) {
306+
name = finalPropName( origName );
307+
}
284308

285309
// Try prefixed name followed by the unprefixed name
286310
hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
@@ -305,6 +329,7 @@ jQuery.extend( {
305329
num = parseFloat( val );
306330
return extra === true || isFinite( num ) ? num || 0 : val;
307331
}
332+
308333
return val;
309334
}
310335
} );

src/css/curCSS.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ function curCSS( elem, name, computed ) {
1515

1616
computed = computed || getStyles( elem );
1717

18-
// Support: IE <=9 only
19-
// getPropertyValue is only needed for .css('filter') (#12537)
18+
// getPropertyValue is needed for:
19+
// .css('filter') (IE 9 only, #12537)
20+
// .css('--customProperty) (#3144)
2021
if ( computed ) {
2122
ret = computed.getPropertyValue( name ) || computed[ name ];
2223

test/unit/css.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,4 +1556,68 @@ QUnit.test( "Do not throw on frame elements from css method (#15098)", function(
15561556

15571557
} )();
15581558

1559+
1560+
QUnit.test( "css(--customProperty)", function( assert ) {
1561+
jQuery( "#qunit-fixture" ).append(
1562+
"<style>\n" +
1563+
" .test__customProperties {\n" +
1564+
" --prop1:val1;\n" +
1565+
" --prop2: val2;\n" +
1566+
" --prop3:val3 ;\n" +
1567+
" --prop4:\"val4\";\n" +
1568+
" --prop5:'val5';\n" +
1569+
" }\n" +
1570+
"</style>"
1571+
);
1572+
1573+
var div = jQuery( "<div>" ).appendTo( "#qunit-fixture" ),
1574+
$elem = jQuery( "<div>" ).addClass( "test__customProperties" ).appendTo( "#qunit-fixture" ),
1575+
webkit = /\bsafari\b/i.test( navigator.userAgent ) &&
1576+
!/\firefox\b/i.test( navigator.userAgent ) &&
1577+
!/\edge\b/i.test( navigator.userAgent ),
1578+
oldSafari = webkit && ( /\b9\.\d(\.\d+)* safari/i.test( navigator.userAgent ) ||
1579+
/\b10\.0(\.\d+)* safari/i.test( navigator.userAgent ) ),
1580+
expected = 10;
1581+
1582+
if ( webkit ) {
1583+
expected -= 2;
1584+
}
1585+
if ( oldSafari ) {
1586+
expected -= 2;
1587+
}
1588+
assert.expect( expected );
1589+
1590+
div.css( "--color", "blue" );
1591+
assert.equal( div.css( "--color" ), "blue", "Modified CSS custom property using string" );
1592+
1593+
div.css( "--color", "yellow" );
1594+
assert.equal( div.css( "--color" ), "yellow", "Overwrite CSS custom property" );
1595+
1596+
div.css( { "--color": "red" } );
1597+
assert.equal( div.css( "--color" ), "red", "Modified CSS custom property using object" );
1598+
1599+
div.css( { "--mixedCase": "green" } );
1600+
assert.equal( div.css( "--mixedCase" ), "green", "Modified CSS custom property with mixed case" );
1601+
1602+
div.css( { "--theme-dark": "purple" } );
1603+
assert.equal( div.css( "--theme-dark" ), "purple", "Modified CSS custom property with dashed name" );
1604+
1605+
assert.equal( $elem.css( "--prop1" ), "val1", "Basic CSS custom property" );
1606+
1607+
// Support: Safari 9.1-10.0 only
1608+
// Safari collapses whitespaces & quotes. Ignore it.
1609+
if ( !oldSafari ) {
1610+
assert.equal( $elem.css( "--prop2" ), " val2", "Preceding whitespace maintained" );
1611+
assert.equal( $elem.css( "--prop3" ), "val3 ", "Following whitespace maintained" );
1612+
}
1613+
1614+
// Support: Chrome 49-55, Safari 9.1-10.0
1615+
// Chrome treats single quotes as double ones.
1616+
// Safari treats double quotes as single ones.
1617+
if ( !webkit ) {
1618+
assert.equal( $elem.css( "--prop4" ), "\"val4\"", "Works with double quotes" );
1619+
assert.equal( $elem.css( "--prop5" ), "'val5'", "Works with single quotes" );
1620+
}
1621+
} );
1622+
15591623
}

0 commit comments

Comments
 (0)