Skip to content

Commit

Permalink
Fix an attribute selector quoting bug (#599)
Browse files Browse the repository at this point in the history
Closes #598
  • Loading branch information
nex3 authored Feb 20, 2019
1 parent b22ae51 commit 26401fb
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 60 deletions.
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 <[email protected]>
homepage: https://github.com/sass/dart-sass
Expand Down

0 comments on commit 26401fb

Please sign in to comment.