@@ -1086,20 +1086,20 @@ abstract class StylesheetParser extends Parser {
10861086 if (next == $u || next == $U ) {
10871087 var url = dynamicUrl ();
10881088 whitespace ();
1089- var queries = tryImportQueries ();
1089+ var modifiers = tryImportModifiers ();
10901090 return StaticImport (Interpolation ([url], scanner.spanFrom (start)),
10911091 scanner.spanFrom (start),
1092- supports : queries ? .item1, media : queries ? .item2 );
1092+ modifiers : modifiers );
10931093 }
10941094
10951095 var url = string ();
10961096 var urlSpan = scanner.spanFrom (start);
10971097 whitespace ();
1098- var queries = tryImportQueries ();
1099- if (isPlainImportUrl (url) || queries != null ) {
1098+ var modifiers = tryImportModifiers ();
1099+ if (isPlainImportUrl (url) || modifiers != null ) {
11001100 return StaticImport (
11011101 Interpolation ([urlSpan.text], urlSpan), scanner.spanFrom (start),
1102- supports : queries ? .item1, media : queries ? .item2 );
1102+ modifiers : modifiers );
11031103 } else {
11041104 try {
11051105 return DynamicImport (parseImportUrl (url), urlSpan);
@@ -1135,54 +1135,100 @@ abstract class StylesheetParser extends Parser {
11351135 return url.startsWith ("http://" ) || url.startsWith ("https://" );
11361136 }
11371137
1138- /// Consumes a supports condition and/or a media query after an `@import` .
1138+ /// Consumes a sequence of modifiers (such as media or supports queries)
1139+ /// after an import argument.
11391140 ///
1140- /// Returns `null` if neither type of query can be found.
1141- Tuple2 <SupportsCondition ?, Interpolation ?>? tryImportQueries () {
1142- SupportsCondition ? supports;
1143- if (scanIdentifier ("supports" )) {
1144- scanner.expectChar ($lparen);
1145- var start = scanner.state;
1146- if (scanIdentifier ("not" )) {
1147- whitespace ();
1148- supports = SupportsNegation (
1149- _supportsConditionInParens (), scanner.spanFrom (start));
1150- } else if (scanner.peekChar () == $lparen) {
1151- supports = _supportsCondition ();
1152- } else {
1153- if (_lookingAtInterpolatedIdentifier ()) {
1154- var identifier = interpolatedIdentifier ();
1155- if (identifier.asPlain? .toLowerCase () == "not" ) {
1156- error ('"not" is not a valid identifier here.' , identifier.span);
1157- }
1141+ /// Returns `null` if there are no modifiers.
1142+ Interpolation ? tryImportModifiers () {
1143+ // Exit before allocating anything if we're not looking at any modifiers, as
1144+ // is the most common case.
1145+ if (! _lookingAtInterpolatedIdentifier () && scanner.peekChar () != $lparen) {
1146+ return null ;
1147+ }
11581148
1159- if (scanner.scanChar ($lparen)) {
1160- var arguments = _interpolatedDeclarationValue (
1161- allowEmpty: true , allowSemicolon: true );
1162- scanner.expectChar ($rparen);
1163- supports = SupportsFunction (
1164- identifier, arguments, scanner.spanFrom (start));
1149+ var start = scanner.state;
1150+ var buffer = InterpolationBuffer ();
1151+ while (true ) {
1152+ if (_lookingAtInterpolatedIdentifier ()) {
1153+ if (! buffer.isEmpty) buffer.writeCharCode ($space);
1154+
1155+ var identifier = interpolatedIdentifier ();
1156+ buffer.addInterpolation (identifier);
1157+
1158+ var name = identifier.asPlain? .toLowerCase ();
1159+ if (name != "and" && scanner.scanChar ($lparen)) {
1160+ if (name == "supports" ) {
1161+ var query = _importSupportsQuery ();
1162+ if (query is ! SupportsDeclaration ) buffer.writeCharCode ($lparen);
1163+ buffer.add (SupportsExpression (query));
1164+ if (query is ! SupportsDeclaration ) buffer.writeCharCode ($rparen);
11651165 } else {
1166- // Backtrack to parse a variable declaration
1167- scanner.state = start;
1166+ buffer.writeCharCode ($lparen);
1167+ buffer.addInterpolation (_interpolatedDeclarationValue (
1168+ allowEmpty: true , allowSemicolon: true ));
1169+ buffer.writeCharCode ($rparen);
1170+ }
1171+
1172+ scanner.expectChar ($rparen);
1173+ whitespace ();
1174+ } else {
1175+ whitespace ();
1176+ if (scanner.scanChar ($comma)) {
1177+ buffer.write (", " );
1178+ buffer.addInterpolation (_mediaQueryList ());
1179+ return buffer.interpolation (scanner.spanFrom (start));
11681180 }
11691181 }
1170- if (supports == null ) {
1171- var name = expression ();
1172- scanner.expectChar ($colon);
1173- supports = _supportsDeclarationValue (name, start);
1174- }
1182+ } else if (scanner.peekChar () == $lparen) {
1183+ if (! buffer.isEmpty) buffer.writeCharCode ($space);
1184+ buffer.addInterpolation (_mediaQueryList ());
1185+ return buffer.interpolation (scanner.spanFrom (start));
1186+ } else {
1187+ return buffer.interpolation (scanner.spanFrom (start));
11751188 }
1176- scanner.expectChar ($rparen);
1189+ }
1190+ }
1191+
1192+ /// Consumes the contents of a `supports()` function after an `@import` rule
1193+ /// (but not the function name or parentheses).
1194+ SupportsCondition _importSupportsQuery () {
1195+ if (scanIdentifier ("not" )) {
11771196 whitespace ();
1197+ var start = scanner.state;
1198+ return SupportsNegation (
1199+ _supportsConditionInParens (), scanner.spanFrom (start));
1200+ } else if (scanner.peekChar () == $lparen) {
1201+ return _supportsCondition ();
1202+ } else {
1203+ var function = _tryImportSupportsFunction ();
1204+ if (function != null ) return function;
1205+
1206+ var start = scanner.state;
1207+ var name = expression ();
1208+ scanner.expectChar ($colon);
1209+ return _supportsDeclarationValue (name, start);
1210+ }
1211+ }
1212+
1213+ /// Consumes a function call within a `supports()` function after an
1214+ /// `@import` if available.
1215+ SupportsFunction ? _tryImportSupportsFunction () {
1216+ if (! _lookingAtInterpolatedIdentifier ()) return null ;
1217+
1218+ var start = scanner.state;
1219+ var name = interpolatedIdentifier ();
1220+ assert (name.asPlain != "not" );
1221+
1222+ if (! scanner.scanChar ($lparen)) {
1223+ scanner.state = start;
1224+ return null ;
11781225 }
11791226
1180- var media =
1181- _lookingAtInterpolatedIdentifier () || scanner.peekChar () == $lparen
1182- ? _mediaQueryList ()
1183- : null ;
1184- if (supports == null && media == null ) return null ;
1185- return Tuple2 (supports, media);
1227+ var value =
1228+ _interpolatedDeclarationValue (allowEmpty: true , allowSemicolon: true );
1229+ scanner.expectChar ($rparen);
1230+
1231+ return SupportsFunction (name, value, scanner.spanFrom (start));
11861232 }
11871233
11881234 /// Consumes an `@include` rule.
0 commit comments