Buggy implementation of CSS @import.

This commit is contained in:
Natalie Weizenbaum 2016-08-28 17:12:03 -07:00 committed by Natalie Weizenbaum
parent 47929dfde3
commit ffb85921cb
9 changed files with 72 additions and 3 deletions

View File

@ -5,6 +5,7 @@
export 'css/at_rule.dart';
export 'css/comment.dart';
export 'css/declaration.dart';
export 'css/import.dart';
export 'css/media_query.dart';
export 'css/media_rule.dart';
export 'css/node.dart';

View File

@ -0,0 +1,18 @@
// 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/interface/css.dart';
import 'node.dart';
class CssImport extends CssNode {
final Uri url;
final FileSpan span;
CssImport(this.url, this.span);
/*=T*/ accept/*<T>*/(CssVisitor/*<T>*/ visitor) => visitor.visitImport(this);
}

View File

@ -33,6 +33,7 @@ export 'sass/statement/import.dart';
export 'sass/statement/include.dart';
export 'sass/statement/media_rule.dart';
export 'sass/statement/mixin_declaration.dart';
export 'sass/statement/plain_import.dart';
export 'sass/statement/return.dart';
export 'sass/statement/style_rule.dart';
export 'sass/statement/stylesheet.dart';

View File

@ -0,0 +1,22 @@
// 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/interface/statement.dart';
import '../expression/string.dart';
import '../statement.dart';
class PlainImport implements Statement {
final Uri url;
final FileSpan span;
PlainImport(this.url, this.span);
/*=T*/ accept/*<T>*/(StatementVisitor/*<T>*/ visitor) =>
visitor.visitPlainImport(this);
String toString() => "@import ${StringExpression.quoteText(url.toString())};";
}

View File

@ -395,17 +395,32 @@ class Parser {
return new If(expression, children, _scanner.spanFrom(start));
}
Import _import(LineScannerState start) {
Statement _import(LineScannerState start) {
if (_inControlDirective) {
_disallowedAtRule(start);
return null;
}
// TODO: wrap error with a span
// TODO: parse supports clauses, url(), and query lists
var urlString = _string(static: true).text.asPlain;
var url = Uri.parse(urlString);
if (_isPlainImportUrl(urlString)) {
return new PlainImport(url, _scanner.spanFrom(start));
} else {
// TODO: wrap error with a span
var url = Uri.parse(_string(static: true).text.asPlain);
return new Import(url, _scanner.spanFrom(start));
}
}
bool _isPlainImportUrl(String url) {
if (url.length < "//".length) return false;
var first = url.codeUnitAt(0);
if (first == $slash) return url.codeUnitAt(1) == $slash;
if (first != $h) return false;
return url.startsWith("http://") || url.startsWith("https://");
}
Include _include(LineScannerState start) {
var name = _identifier();
_ignoreComments();

View File

@ -10,6 +10,7 @@ abstract class CssVisitor<T> extends SelectorVisitor<T>
implements ValueVisitor<T> {
T visitComment(CssComment node) => null;
T visitDeclaration(CssDeclaration node) => null;
T visitImport(CssImport node) => null;
T visitAtRule(CssAtRule node) {
if (node.children == null) return null;

View File

@ -9,6 +9,7 @@ abstract class StatementVisitor<T> {
T visitContent(Content node) => null;
T visitExtendRule(ExtendRule node) => null;
T visitImport(Import node) => null;
T visitPlainImport(PlainImport node) => null;
T visitReturn(Return node) => null;
T visitVariableDeclaration(VariableDeclaration node) => null;

View File

@ -291,6 +291,9 @@ class PerformVisitor extends StatementVisitor
return new CssMediaQuery(type, modifier: modifier, features: features);
}
CssImport visitPlainImport(PlainImport node) =>
new CssImport(node.url, node.span);
Value visitReturn(Return node) => node.expression.accept(this);
void visitStyleRule(StyleRule node) {

View File

@ -95,6 +95,13 @@ class _SerializeCssVisitor extends CssVisitor {
_visitChildren(node.children);
}
void visitImport(CssImport node) {
_writeIndentation();
_buffer.write("@import ");
_visitString(node.url.toString());
_buffer.writeCharCode($semicolon);
}
void visitMediaQuery(CssMediaQuery query) {
if (query.modifier != null) {
_buffer.write(query.modifier.value);