Add Sass media query classes.

This commit is contained in:
Natalie Weizenbaum 2016-07-08 14:46:57 -07:00
parent e94e55f642
commit d063b41e64
5 changed files with 96 additions and 14 deletions

View File

@ -0,0 +1,48 @@
// 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:source_span/source_span.dart';
import '../../utils.dart';
import '../node.dart';
import 'expression.dart';
import 'node.dart';
class MediaQuery implements SassNode {
final InterpolationExpression modifier;
final InterpolationExpression type;
final List<InterpolationExpression> features;
FileSpan get span {
var components = <AstNode>[];
if (modifier != null) components.add(modifier);
if (type != null) components.add(type);
components.addAll(features);
return spanForList(components);
}
MediaQuery(this.type, {this.modifier,
Iterable<InterpolationExpression> features})
: features = features == null
? const []
: new List.unmodifiable(features);
MediaQuery.condition(Iterable<InterpolationExpression> features,
{this.modifier, this.type})
: features = new List.unmodifiable(features);
String toString() {
var buffer = new StringBuffer();
if (modifier != null) buffer.write("$modifier ");
if (type != null) {
buffer.write(type);
if (features.isNotEmpty) buffer.write(" and ");
}
buffer.write(features.join(" and "));
return buffer.toString();
}
}

View File

@ -0,0 +1,26 @@
// 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:source_span/source_span.dart';
import '../../visitor/sass/statement.dart';
import 'statement.dart';
class MediaRule implements Statement {
final List<MediaQuery> queries;
final List<Statement> children;
final FileSpan span;
MediaRule(Iterable<MediaQuery> queries, Iterable<Statement> children,
{this.span})
: queries = new List.unmodifiable(queries),
children = new List.unmodifiable(children);
/*=T*/ accept/*<T>*/(StatementVisitor/*<T>*/ visitor) =>
visitor.visitMediaRule(this);
String toString() => "@media ${queries.join(", ")} {${children.join(" ")}}";
}

View File

@ -8,6 +8,8 @@ import 'node.dart';
export 'at_rule.dart';
export 'comment.dart';
export 'declaration.dart';
export 'media_query.dart';
export 'media_rule.dart';
export 'style_rule.dart';
export 'stylesheet.dart';
export 'variable_declaration.dart';

View File

@ -108,6 +108,11 @@ class Parser {
var name = _identifier();
_ignoreComments();
if (name == "media") {
return new MediaRule(_mediaQueryList(), _ruleChildren(),
span: _scanner.spanFrom(start));
}
InterpolationExpression value;
var next = _scanner.peekChar();
if (next != $exclamation && next != $semicolon && next != $lbrace &&
@ -969,19 +974,16 @@ class Parser {
// ## Media Queries
MediaQueryList _mediaQueryList() {
var start = _scanner.state;
List<MediaQuery> _mediaQueryList() {
var queries = <MediaQuery>[];
do {
_ignoreComments();
queries.add(_mediaQuery());
} while (_scanner.scanChar($comma));
return new MediaQueryList(queries, span: _scanner.spanFrom(start));
return queries;
}
MediaQuery _mediaQuery() {
var start = _scanner.state;
InterpolationExpression modifier;
InterpolationExpression type;
if (_scanner.peekChar() != $lparen) {
@ -990,7 +992,7 @@ class Parser {
if (!_lookingAtInterpolatedIdentifier()) {
// For example, "@media screen {"
return new MediaQuery(identifier1, span: _scanner.spanFrom(start));
return new MediaQuery(identifier1);
}
var identifier2 = _interpolatedIdentifier();
@ -1007,8 +1009,7 @@ class Parser {
_ignoreComments();
} else {
// For example, "@media only screen {"
return new MediaQuery(type,
modifier: modifier, span: _scanner.spanFrom(start));
return new MediaQuery(type, modifier: modifier);
}
}
}
@ -1016,18 +1017,16 @@ class Parser {
// We've consumed either `IDENTIFIER "and"` or
// `IDENTIFIER IDENTIFIER "and"`.
var expressions = <InterpolationExpression>[];
var features = <InterpolationExpression>[];
do {
_ignoreComments();
expressions.add(_mediaExpression());
features.add(_mediaExpression());
} while (_scanCaseInsensitive("and"));
if (type == null) {
return new MediaQuery.expressions(expressions,
span: _scanner.spanFrom(start));
return new MediaQuery.condition(features);
} else {
return new MediaQuery(type, modifier: modifier, expressions: expressions,
span: _scanner.spanFrom(start));
return new MediaQuery(type, modifier: modifier, features: features);
}
}

View File

@ -17,6 +17,13 @@ class StatementVisitor<T> {
return null;
}
T visitMediaRule(MediaRule node) {
for (var child in node.children) {
child.accept(this);
}
return null;
}
T visitStyleRule(StyleRule node) {
for (var child in node.children) {
child.accept(this);