Add deprecation warnings for hex alpha colors (#367)

Also support unambiguous hex alpha colors.

Closes #360
See sass/sass#2179
This commit is contained in:
Natalie Weizenbaum 2018-06-21 17:47:06 -07:00 committed by GitHub
parent d6dc8c9d15
commit 023bf91745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 80 additions and 20 deletions

View File

@ -1,4 +1,10 @@
## 1.6.3
## 1.7.0
* Emit deprecation warnings for tokens such as `#abcd` that are ambiguous
between ID strings and hex colors with alpha channels. These will be
interpreted as colors in a release on or after 19 September 2018.
* Parse unambiguous hex colors with alpha channels as colors.
* Fix a bug where relative imports from files on the load path could look in the
incorrect location.

View File

@ -1742,7 +1742,20 @@ abstract class StylesheetParser extends Parser {
var identifier = _interpolatedIdentifier();
if (_isHexColor(identifier)) {
scanner.state = afterHash;
return new ColorExpression(_hexColorContents(start));
var color = _hexColorContents(start);
var plain = identifier.asPlain;
if (plain.length == 4 || plain.length == 8) {
logger.warn('''
The value "$color" is currently parsed as a string, but it will be parsed as a
color in a release on or after 19 September 2018.
To continue parsing it as a string, use "unquote('$color')".
To parse it as a color, use "${color.toStringAsRgb()}".
''', span: color.originalSpan, deprecation: true);
} else {
return new ColorExpression(color);
}
}
var buffer = new InterpolationBuffer();
@ -1753,22 +1766,39 @@ abstract class StylesheetParser extends Parser {
/// Consumes the contents of a hex color, after the `#`.
SassColor _hexColorContents(LineScannerState start) {
var red = _hexDigit();
var green = _hexDigit();
var blue = _hexDigit();
var digit1 = _hexDigit();
var digit2 = _hexDigit();
var digit3 = _hexDigit();
var next = scanner.peekChar();
if (next != null && isHex(next)) {
red = (red << 4) + green;
green = (blue << 4) + _hexDigit();
blue = (_hexDigit() << 4) + _hexDigit();
int red;
int green;
int blue;
num alpha = 1;
if (!isHex(scanner.peekChar())) {
// #abc
red = (digit1 << 4) + digit1;
green = (digit2 << 4) + digit2;
blue = (digit3 << 4) + digit3;
} else {
red = (red << 4) + red;
green = (green << 4) + green;
blue = (blue << 4) + blue;
var digit4 = _hexDigit();
if (!isHex(scanner.peekChar())) {
// #abcd
red = (digit1 << 4) + digit1;
green = (digit2 << 4) + digit2;
blue = (digit3 << 4) + digit3;
alpha = ((digit4 << 4) + digit4) / 0xff;
} else {
red = (digit1 << 4) + digit2;
green = (digit3 << 4) + digit4;
blue = (_hexDigit() << 4) + _hexDigit();
if (isHex(scanner.peekChar())) {
alpha = ((_hexDigit() << 4) + _hexDigit()) / 0xff;
}
}
}
return new SassColor.rgb(red, green, blue, 1, scanner.spanFrom(start));
return new SassColor.rgb(red, green, blue, alpha, scanner.spanFrom(start));
}
/// Returns whether [interpolation] is a plain string that can be parsed as a
@ -1776,7 +1806,12 @@ abstract class StylesheetParser extends Parser {
bool _isHexColor(Interpolation interpolation) {
var plain = interpolation.asPlain;
if (plain == null) return false;
if (plain.length != 3 && plain.length != 6) return false;
if (plain.length != 3 &&
plain.length != 4 &&
plain.length != 6 &&
plain.length != 8) {
return false;
}
return plain.codeUnits.every(isHex);
}

View File

@ -43,10 +43,13 @@ bool isName(int character) =>
isNameStart(character) || isDigit(character) || character == $minus;
/// Returns whether [character] is a hexadeicmal digit.
bool isHex(int character) =>
isDigit(character) ||
(character >= $a && character <= $f) ||
(character >= $A && character <= $F);
bool isHex(int character) {
if (character == null) return false;
if (isDigit(character)) return true;
if (character >= $a && character <= $f) return true;
if (character >= $A && character <= $F) return true;
return false;
}
/// Returns whether [character] is the beginning of a UTF-16 surrogate pair.
bool isHighSurrogate(int character) =>

View File

@ -201,4 +201,20 @@ class SassColor extends Value implements ext.SassColor {
return fuzzyRound(result * 255);
}
/// Returns an `rgb()` or `rgba()` function call that will evaluate to this
/// color.
String toStringAsRgb() {
var isOpaque = fuzzyEquals(alpha, 1);
var buffer = new StringBuffer(isOpaque ? "rgb" : "rgba")
..write("($red, $green, $blue");
if (!isOpaque) {
// Write the alpha as a SassNumber to ensure it's valid CSS.
buffer.write(", ${new SassNumber(alpha)}");
}
buffer.write(")");
return buffer.toString();
}
}

View File

@ -1,5 +1,5 @@
name: sass
version: 1.6.3-dev
version: 1.7.0
description: A Sass implementation in Dart.
author: Dart Team <misc@dartlang.org>
homepage: https://github.com/sass/dart-sass