Skip to content

Commit f7669d5

Browse files
authored
Properly parse custom property values in @supports conditions (#1570)
Closes sass/sass#3216
1 parent 6b35eb6 commit f7669d5

File tree

5 files changed

+50
-10
lines changed

5 files changed

+50
-10
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## 1.45.1
22

3+
* **Potentially breaking bug fix:** Properly parse custom properties in
4+
`@supports` conditions. Note that this means that SassScript expressions on
5+
the right-hand side of custom property `@supports` queries now need to be
6+
interpolated, as per https://sass-lang.com/d/css-vars.
7+
38
* **Potentially breaking bug fix:** Fix a bug where `inspect()` was not
49
properly printing nested, empty, bracketed lists.
510

lib/src/ast/sass/supports_condition/declaration.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:meta/meta.dart';
66
import 'package:source_span/source_span.dart';
77

88
import '../expression.dart';
9+
import '../expression/string.dart';
910
import '../supports_condition.dart';
1011

1112
/// A condition that selects for browsers where a given declaration is
@@ -22,6 +23,23 @@ class SupportsDeclaration implements SupportsCondition {
2223

2324
final FileSpan span;
2425

26+
/// Returns whether this is a CSS Custom Property declaration.
27+
///
28+
/// Note that this can return `false` for declarations that will ultimately be
29+
/// serialized as custom properties if they aren't *parsed as* custom
30+
/// properties, such as `#{--foo}: ...`.
31+
///
32+
/// If this is `true`, then `value` will be a [StringExpression].
33+
///
34+
/// @nodoc
35+
@internal
36+
bool get isCustomProperty {
37+
var name = this.name;
38+
return name is StringExpression &&
39+
!name.hasQuotes &&
40+
name.text.initialPlain.startsWith('--');
41+
}
42+
2543
SupportsDeclaration(this.name, this.value, this.span);
2644

2745
String toString() => "($name: $value)";

lib/src/parse/stylesheet.dart

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,9 +1172,7 @@ abstract class StylesheetParser extends Parser {
11721172
if (supports == null) {
11731173
var name = expression();
11741174
scanner.expectChar($colon);
1175-
whitespace();
1176-
var value = expression();
1177-
supports = SupportsDeclaration(name, value, scanner.spanFrom(start));
1175+
supports = _supportsDeclarationValue(name, start);
11781176
}
11791177
}
11801178
scanner.expectChar($rparen);
@@ -3611,9 +3609,24 @@ abstract class StylesheetParser extends Parser {
36113609
return SupportsAnything(contents, scanner.spanFrom(start));
36123610
}
36133611

3614-
whitespace();
3615-
var value = expression();
3612+
var declaration = _supportsDeclarationValue(name, start);
36163613
scanner.expectChar($rparen);
3614+
return declaration;
3615+
}
3616+
3617+
/// Parses and returns the right-hand side of a declaration in a supports
3618+
/// query.
3619+
SupportsDeclaration _supportsDeclarationValue(
3620+
Expression name, LineScannerState start) {
3621+
Expression value;
3622+
if (name is StringExpression &&
3623+
!name.hasQuotes &&
3624+
name.text.initialPlain.startsWith("--")) {
3625+
value = StringExpression(_interpolatedDeclarationValue());
3626+
} else {
3627+
whitespace();
3628+
value = expression();
3629+
}
36173630
return SupportsDeclaration(name, value, scanner.spanFrom(start));
36183631
}
36193632

lib/src/visitor/async_evaluate.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,7 +1656,8 @@ class _EvaluateVisitor
16561656
var url = await _interpolationToValue(import.url);
16571657
var supports = await import.supports.andThen((supports) async {
16581658
var arg = supports is SupportsDeclaration
1659-
? "${await _evaluateToCss(supports.name)}: "
1659+
? "${await _evaluateToCss(supports.name)}:"
1660+
"${supports.isCustomProperty ? '' : ' '}"
16601661
"${await _evaluateToCss(supports.value)}"
16611662
: await supports.andThen(_visitSupportsCondition);
16621663
return CssValue("supports($arg)", supports.span);
@@ -1941,7 +1942,8 @@ class _EvaluateVisitor
19411942
} else if (condition is SupportsInterpolation) {
19421943
return await _evaluateToCss(condition.expression, quote: false);
19431944
} else if (condition is SupportsDeclaration) {
1944-
return "(${await _evaluateToCss(condition.name)}: "
1945+
return "(${await _evaluateToCss(condition.name)}:"
1946+
"${condition.isCustomProperty ? '' : ' '}"
19451947
"${await _evaluateToCss(condition.value)})";
19461948
} else if (condition is SupportsFunction) {
19471949
return "${await _performInterpolation(condition.name)}("

lib/src/visitor/evaluate.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
// DO NOT EDIT. This file was generated from async_evaluate.dart.
66
// See tool/grind/synchronize.dart for details.
77
//
8-
// Checksum: 96397ede2c79b09005bbac9a013d4a6b42faf736
8+
// Checksum: c1d303225e5cac5e32dd32a4eed30a71a35b390c
99
//
1010
// ignore_for_file: unused_import
1111

@@ -1653,7 +1653,8 @@ class _EvaluateVisitor
16531653
var url = _interpolationToValue(import.url);
16541654
var supports = import.supports.andThen((supports) {
16551655
var arg = supports is SupportsDeclaration
1656-
? "${_evaluateToCss(supports.name)}: "
1656+
? "${_evaluateToCss(supports.name)}:"
1657+
"${supports.isCustomProperty ? '' : ' '}"
16571658
"${_evaluateToCss(supports.value)}"
16581659
: supports.andThen(_visitSupportsCondition);
16591660
return CssValue("supports($arg)", supports.span);
@@ -1934,7 +1935,8 @@ class _EvaluateVisitor
19341935
} else if (condition is SupportsInterpolation) {
19351936
return _evaluateToCss(condition.expression, quote: false);
19361937
} else if (condition is SupportsDeclaration) {
1937-
return "(${_evaluateToCss(condition.name)}: "
1938+
return "(${_evaluateToCss(condition.name)}:"
1939+
"${condition.isCustomProperty ? '' : ' '}"
19381940
"${_evaluateToCss(condition.value)})";
19391941
} else if (condition is SupportsFunction) {
19401942
return "${_performInterpolation(condition.name)}("

0 commit comments

Comments
 (0)