Support url() imports.

This commit is contained in:
Natalie Weizenbaum 2016-10-04 23:29:36 -07:00 committed by Natalie Weizenbaum
parent c4ea6012dc
commit 2289901df8
5 changed files with 40 additions and 18 deletions

View File

@ -6,11 +6,14 @@ import 'package:source_span/source_span.dart';
import '../../visitor/interface/css.dart';
import 'node.dart';
import 'value.dart';
/// A plain CSS `@import`.
class CssImport extends CssNode {
/// The URL being imported.
final Uri url;
///
/// This includes quotes.
final CssValue<String> url;
final FileSpan span;

View File

@ -5,11 +5,11 @@
import 'package:source_span/source_span.dart';
import '../../../visitor/interface/statement.dart';
import '../expression/string.dart';
import '../interpolation.dart';
import '../statement.dart';
class PlainImportRule implements Statement {
final Uri url;
final Interpolation url;
final FileSpan span;
@ -18,5 +18,5 @@ class PlainImportRule implements Statement {
/*=T*/ accept/*<T>*/(StatementVisitor/*<T>*/ visitor) =>
visitor.visitPlainImportRule(this);
String toString() => "@import ${StringExpression.quoteText(url.toString())};";
String toString() => "@import $url;";
}

View File

@ -523,20 +523,27 @@ abstract class StylesheetParser extends Parser {
}
// TODO: parse supports clauses, url(), and query lists
var urlString = string();
Uri url;
try {
url = Uri.parse(urlString);
} on FormatException catch (error) {
throw new SassFormatException(
"Invalid URL: ${error.message}", scanner.spanFrom(start));
var urlStart = scanner.state;
var next = scanner.peekChar();
if (next == $u || next == $U) {
return new PlainImportRule(
new Interpolation([_dynamicUrl()], scanner.spanFrom(urlStart)),
scanner.spanFrom(start));
}
if (_isPlainImportUrl(urlString)) {
return new PlainImportRule(url, scanner.spanFrom(start));
var url = string();
if (_isPlainImportUrl(url)) {
return new PlainImportRule(
new Interpolation([scanner.substring(urlStart.position)],
scanner.spanFrom(urlStart)),
scanner.spanFrom(start));
} else {
return new ImportRule(url, scanner.spanFrom(start));
try {
return new ImportRule(Uri.parse(url), scanner.spanFrom(start));
} on FormatException catch (error) {
throw new SassFormatException(
"Invalid URL: ${error.message}", scanner.spanFrom(start));
}
}
}
@ -1499,6 +1506,17 @@ abstract class StylesheetParser extends Parser {
return null;
}
Expression _dynamicUrl() {
var start = scanner.state;
expectIdentifier("url", ignoreCase: true);
var contents = _tryUrlContents(start);
if (contents != null) return new StringExpression(contents);
return new FunctionExpression(
new Interpolation(["url"], scanner.spanFrom(start)),
_argumentInvocation());
}
/// Consumes tokens up to "{", "}", ";", or "!".
///
/// This respects string and comment boundaries and supports interpolation.

View File

@ -481,8 +481,9 @@ class PerformVisitor implements StatementVisitor, ExpressionVisitor<Value> {
return new CssMediaQuery(type, modifier: modifier, features: features);
}
CssImport visitPlainImportRule(PlainImportRule node) =>
new CssImport(node.url, node.span);
void visitPlainImportRule(PlainImportRule node) {
_parent.addChild(new CssImport(_interpolationToValue(node.url), node.span));
}
Value visitReturnRule(ReturnRule node) => node.expression.accept(this);

View File

@ -110,7 +110,7 @@ class _SerializeCssVisitor
void visitImport(CssImport node) {
_writeIndentation();
_buffer.write("@import ");
_visitString(node.url.toString());
_buffer.write(node.url.value);
_buffer.writeCharCode($semicolon);
}