Skip to content

Commit

Permalink
Properly parse custom property values in @supports conditions (#1570)
Browse files Browse the repository at this point in the history
  • Loading branch information
nex3 committed Dec 11, 2021
1 parent 6b35eb6 commit f7669d5
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 10 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## 1.45.1

* **Potentially breaking bug fix:** Properly parse custom properties in
`@supports` conditions. Note that this means that SassScript expressions on
the right-hand side of custom property `@supports` queries now need to be
interpolated, as per https://sass-lang.com/d/css-vars.

* **Potentially breaking bug fix:** Fix a bug where `inspect()` was not
properly printing nested, empty, bracketed lists.

Expand Down
18 changes: 18 additions & 0 deletions lib/src/ast/sass/supports_condition/declaration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:meta/meta.dart';
import 'package:source_span/source_span.dart';

import '../expression.dart';
import '../expression/string.dart';
import '../supports_condition.dart';

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

final FileSpan span;

/// Returns whether this is a CSS Custom Property declaration.
///
/// Note that this can return `false` for declarations that will ultimately be
/// serialized as custom properties if they aren't *parsed as* custom
/// properties, such as `#{--foo}: ...`.
///
/// If this is `true`, then `value` will be a [StringExpression].
///
/// @nodoc
@internal
bool get isCustomProperty {
var name = this.name;
return name is StringExpression &&
!name.hasQuotes &&
name.text.initialPlain.startsWith('--');
}

SupportsDeclaration(this.name, this.value, this.span);

String toString() => "($name: $value)";
Expand Down
23 changes: 18 additions & 5 deletions lib/src/parse/stylesheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1172,9 +1172,7 @@ abstract class StylesheetParser extends Parser {
if (supports == null) {
var name = expression();
scanner.expectChar($colon);
whitespace();
var value = expression();
supports = SupportsDeclaration(name, value, scanner.spanFrom(start));
supports = _supportsDeclarationValue(name, start);
}
}
scanner.expectChar($rparen);
Expand Down Expand Up @@ -3611,9 +3609,24 @@ abstract class StylesheetParser extends Parser {
return SupportsAnything(contents, scanner.spanFrom(start));
}

whitespace();
var value = expression();
var declaration = _supportsDeclarationValue(name, start);
scanner.expectChar($rparen);
return declaration;
}

/// Parses and returns the right-hand side of a declaration in a supports
/// query.
SupportsDeclaration _supportsDeclarationValue(
Expression name, LineScannerState start) {
Expression value;
if (name is StringExpression &&
!name.hasQuotes &&
name.text.initialPlain.startsWith("--")) {
value = StringExpression(_interpolatedDeclarationValue());
} else {
whitespace();
value = expression();
}
return SupportsDeclaration(name, value, scanner.spanFrom(start));
}

Expand Down
6 changes: 4 additions & 2 deletions lib/src/visitor/async_evaluate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1656,7 +1656,8 @@ class _EvaluateVisitor
var url = await _interpolationToValue(import.url);
var supports = await import.supports.andThen((supports) async {
var arg = supports is SupportsDeclaration
? "${await _evaluateToCss(supports.name)}: "
? "${await _evaluateToCss(supports.name)}:"
"${supports.isCustomProperty ? '' : ' '}"
"${await _evaluateToCss(supports.value)}"
: await supports.andThen(_visitSupportsCondition);
return CssValue("supports($arg)", supports.span);
Expand Down Expand Up @@ -1941,7 +1942,8 @@ class _EvaluateVisitor
} else if (condition is SupportsInterpolation) {
return await _evaluateToCss(condition.expression, quote: false);
} else if (condition is SupportsDeclaration) {
return "(${await _evaluateToCss(condition.name)}: "
return "(${await _evaluateToCss(condition.name)}:"
"${condition.isCustomProperty ? '' : ' '}"
"${await _evaluateToCss(condition.value)})";
} else if (condition is SupportsFunction) {
return "${await _performInterpolation(condition.name)}("
Expand Down
8 changes: 5 additions & 3 deletions lib/src/visitor/evaluate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// DO NOT EDIT. This file was generated from async_evaluate.dart.
// See tool/grind/synchronize.dart for details.
//
// Checksum: 96397ede2c79b09005bbac9a013d4a6b42faf736
// Checksum: c1d303225e5cac5e32dd32a4eed30a71a35b390c
//
// ignore_for_file: unused_import

Expand Down Expand Up @@ -1653,7 +1653,8 @@ class _EvaluateVisitor
var url = _interpolationToValue(import.url);
var supports = import.supports.andThen((supports) {
var arg = supports is SupportsDeclaration
? "${_evaluateToCss(supports.name)}: "
? "${_evaluateToCss(supports.name)}:"
"${supports.isCustomProperty ? '' : ' '}"
"${_evaluateToCss(supports.value)}"
: supports.andThen(_visitSupportsCondition);
return CssValue("supports($arg)", supports.span);
Expand Down Expand Up @@ -1934,7 +1935,8 @@ class _EvaluateVisitor
} else if (condition is SupportsInterpolation) {
return _evaluateToCss(condition.expression, quote: false);
} else if (condition is SupportsDeclaration) {
return "(${_evaluateToCss(condition.name)}: "
return "(${_evaluateToCss(condition.name)}:"
"${condition.isCustomProperty ? '' : ' '}"
"${_evaluateToCss(condition.value)})";
} else if (condition is SupportsFunction) {
return "${_performInterpolation(condition.name)}("
Expand Down

0 comments on commit f7669d5

Please sign in to comment.