dart-sass/lib/src/parse/media_query.dart

78 lines
2.1 KiB
Dart
Raw Normal View History

2016-10-29 01:55:56 +02:00
// Copyright 2016 Google Inc. Use of this source code is governed by an
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.
import 'package:charcode/charcode.dart';
import '../ast/css.dart';
import '../utils.dart';
import 'parser.dart';
/// A parser for `@media` queries.
class MediaQueryParser extends Parser {
MediaQueryParser(String contents, {url}) : super(contents, url: url);
List<CssMediaQuery> parse() {
return wrapSpanFormatException(() {
var queries = <CssMediaQuery>[];
do {
whitespace();
queries.add(_mediaQuery());
} while (scanner.scanChar($comma));
return queries;
});
}
/// Consumes a single media query.
CssMediaQuery _mediaQuery() {
// This is somewhat duplicated in StylesheetParser._mediaQuery.
String modifier;
String type;
if (scanner.peekChar() != $lparen) {
var identifier1 = identifier();
whitespace();
if (!lookingAtIdentifier()) {
// For example, "@media screen {"
return new CssMediaQuery(identifier1);
}
var identifier2 = identifier();
whitespace();
if (equalsIgnoreCase(identifier2, "and")) {
// For example, "@media screen and ..."
type = identifier1;
} else {
modifier = identifier1;
type = identifier2;
if (scanIdentifier("and", ignoreCase: true)) {
// For example, "@media only screen and ..."
whitespace();
} else {
// For example, "@media only screen {"
return new CssMediaQuery(type, modifier: modifier);
}
}
}
// We've consumed either `IDENTIFIER "and"` or
// `IDENTIFIER IDENTIFIER "and"`.
var features = <String>[];
do {
whitespace();
scanner.expectChar($lparen);
features.add("(${declarationValue()})");
scanner.expectChar($rparen);
whitespace();
} while (scanIdentifier("and", ignoreCase: true));
if (type == null) {
return new CssMediaQuery.condition(features);
} else {
return new CssMediaQuery(type, modifier: modifier, features: features);
}
}
}