Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix an attribute selector quoting bug #599

Merged
merged 1 commit into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 1.17.1

* Properly quote attribute selector values that start with identifiers but end
with a non-identifier character.

## 1.17.0

* Improve error output, particularly for errors that cover multiple lines.
Expand Down
10 changes: 10 additions & 0 deletions lib/src/parse/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ class Parser {
static String parseIdentifier(String text, {Logger logger}) =>
Parser(text, logger: logger)._parseIdentifier();

/// Returns whether [text] is a valid CSS identifier.
static bool isIdentifier(String text, {Logger logger}) {
try {
parseIdentifier(text, logger: logger);
return true;
} on SassFormatException {
return false;
}
}

@protected
Parser(String contents, {url, Logger logger})
: scanner = SpanScanner(contents, sourceUrl: url),
Expand Down
64 changes: 5 additions & 59 deletions lib/src/visitor/serialize.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import '../ast/node.dart';
import '../ast/selector.dart';
import '../color_names.dart';
import '../exception.dart';
import '../parse/parser.dart';
import '../utils.dart';
import '../util/character.dart';
import '../util/no_source_map_buffer.dart';
Expand Down Expand Up @@ -903,7 +904,10 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
_buffer.write(attribute.name);
if (attribute.op != null) {
_buffer.write(attribute.op);
if (_isIdentifier(attribute.value)) {
if (Parser.isIdentifier(attribute.value) &&
// Emit identifiers that start with `--` with quotes, because IE11
// doesn't consider them to be valid identifiers.
!attribute.value.startsWith('--')) {
_buffer.write(attribute.value);
} else {
_visitQuotedString(attribute.value);
Expand Down Expand Up @@ -1133,64 +1137,6 @@ class _SerializeVisitor implements CssVisitor, ValueVisitor, SelectorVisitor {
return false;
}
}

/// Returns whether [text] is a valid identifier.
///
/// This *doesn't* consider identifiers beginning with `--` to be valid,
/// because IE 11 doesn't.
bool _isIdentifier(String text) {
var scanner = StringScanner(text);
scanner.scanChar($dash);

if (scanner.isDone) return false;
var first = scanner.readChar();

if (isNameStart(first)) {
if (scanner.isDone) return true;
scanner.readChar();
} else if (first == $backslash) {
if (!_consumeEscape(scanner)) return false;
} else {
return false;
}

while (true) {
var next = scanner.peekChar();
if (next == null) return true;

if (isName(next)) {
scanner.readChar();
} else if (next == $backslash) {
if (!_consumeEscape(scanner)) return false;
} else {
return false;
}
}
}

/// Consumes an escape sequence in [scanner].
///
/// Returns whether a valid escape was consumed.
bool _consumeEscape(StringScanner scanner) {
scanner.expectChar($backslash);

var first = scanner.peekChar();
if (first == null || isNewline(first)) return false;

if (isHex(first)) {
for (var i = 0; i < 6; i++) {
var next = scanner.peekChar();
if (next == null || !isHex(next)) break;
scanner.readChar();
}
if (isWhitespace(scanner.peekChar())) scanner.readChar();
} else {
if (scanner.isDone) return false;
scanner.readChar();
}

return true;
}
}

/// An enum of generated CSS styles.
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: sass
version: 1.17.0
version: 1.17.1
description: A Sass implementation in Dart.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/sass/dart-sass
Expand Down