Merge pull request #24 from sass/serialize-color

Match Ruby Sass's color serialization.
This commit is contained in:
Natalie Weizenbaum 2016-11-03 12:13:09 -07:00 committed by GitHub
commit 6da45c827d
7 changed files with 56 additions and 7 deletions

View File

@ -1,3 +1,9 @@
## 1.0.0-alpha.3
* Emit colors using their original representation if possible.
* Emit colors without an original representation as names if possible.
## 1.0.0-alpha.2 ## 1.0.0-alpha.2
* Fix a bug where variables, functions, and mixins were broken in imported * Fix a bug where variables, functions, and mixins were broken in imported

View File

@ -2,6 +2,8 @@
// MIT-style license that can be found in the LICENSE file or at // MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT. // https://opensource.org/licenses/MIT.
import 'package:collection/collection.dart';
import 'utils.dart'; import 'utils.dart';
import 'value.dart'; import 'value.dart';
@ -157,3 +159,9 @@ final colorsByName = normalizedMap({
'yellow': new SassColor.rgb(0xFF, 0xFF, 0x00), 'yellow': new SassColor.rgb(0xFF, 0xFF, 0x00),
'yellowgreen': new SassColor.rgb(0x9A, 0xCD, 0x32), 'yellowgreen': new SassColor.rgb(0x9A, 0xCD, 0x32),
}); });
/// A map from Sass colors to (lowercase) color names.
final namesByColor = mapMap/*<String, SassColor, SassColor, String>*/(
colorsByName,
key: (_, color) => color,
value: (name, _) => name);

View File

@ -15,6 +15,7 @@ import '../interpolation_buffer.dart';
import '../util/character.dart'; import '../util/character.dart';
import '../utils.dart'; import '../utils.dart';
import '../value.dart'; import '../value.dart';
import '../value/color.dart';
import 'parser.dart'; import 'parser.dart';
/// The base class for both the SCSS and indented syntax parsers. /// The base class for both the SCSS and indented syntax parsers.
@ -1492,14 +1493,20 @@ abstract class StylesheetParser extends Parser {
var first = scanner.peekChar(); var first = scanner.peekChar();
if (first != null && isDigit(first)) { if (first != null && isDigit(first)) {
return new ColorExpression(_hexColorContents(), scanner.spanFrom(start)); var color = _hexColorContents();
var span = scanner.spanFrom(start);
setOriginalSpan(color, span);
return new ColorExpression(color, span);
} }
var afterHash = scanner.state; var afterHash = scanner.state;
var identifier = _interpolatedIdentifier(); var identifier = _interpolatedIdentifier();
if (_isHexColor(identifier)) { if (_isHexColor(identifier)) {
scanner.state = afterHash; scanner.state = afterHash;
return new ColorExpression(_hexColorContents(), scanner.spanFrom(start)); var color = _hexColorContents();
var span = scanner.spanFrom(start);
setOriginalSpan(color, span);
return new ColorExpression(color, span);
} }
var buffer = new InterpolationBuffer(); var buffer = new InterpolationBuffer();
@ -1740,7 +1747,13 @@ abstract class StylesheetParser extends Parser {
} }
var color = colorsByName[lower]; var color = colorsByName[lower];
if (color != null) return new ColorExpression(color, identifier.span); if (color != null) {
// TODO(nweiz): Avoid copying the color in compressed mode.
color = new SassColor.rgb(
color.red, color.green, color.blue, color.alpha);
setOriginalSpan(color, identifier.span);
return new ColorExpression(color, identifier.span);
}
} }
var specialFunction = _trySpecialFunction(lower, start); var specialFunction = _trySpecialFunction(lower, start);

View File

@ -16,7 +16,7 @@ import 'visitor/serialize.dart';
export 'value/argument_list.dart'; export 'value/argument_list.dart';
export 'value/boolean.dart'; export 'value/boolean.dart';
export 'value/color.dart'; export 'value/color.dart' hide setOriginalSpan;
export 'value/function.dart'; export 'value/function.dart';
export 'value/list.dart'; export 'value/list.dart';
export 'value/map.dart'; export 'value/map.dart';

View File

@ -4,11 +4,20 @@
import 'dart:math' as math; import 'dart:math' as math;
import 'package:source_span/source_span.dart';
import '../exception.dart'; import '../exception.dart';
import '../util/number.dart'; import '../util/number.dart';
import '../value.dart'; import '../value.dart';
import '../visitor/interface/value.dart'; import '../visitor/interface/value.dart';
/// Sets the span for [SassColor.original] to [span].
///
/// This is a separate function so it can be hidden in most exports.
void setOriginalSpan(SassColor color, SourceSpan span) {
color._originalSpan = span;
}
// TODO(nweiz): track original representation. // TODO(nweiz): track original representation.
/// A SassScript color. /// A SassScript color.
class SassColor extends Value { class SassColor extends Value {
@ -63,6 +72,15 @@ class SassColor extends Value {
/// This color's alpha channel, between `0` and `1`. /// This color's alpha channel, between `0` and `1`.
final num alpha; final num alpha;
/// The original string representation of this color, or `null` if one is
/// unavailable.
String get original => _originalSpan?.text;
/// The span tracking the location in which this color was originally defined.
///
/// This is tracked as a span to avoid extra substring allocations.
SourceSpan _originalSpan;
/// Creates an RGB color. /// Creates an RGB color.
/// ///
/// Throws a [RangeError] if [red], [green], and [blue] aren't between `0` and /// Throws a [RangeError] if [red], [green], and [blue] aren't between `0` and

View File

@ -10,6 +10,7 @@ import 'package:string_scanner/string_scanner.dart';
import '../ast/css.dart'; import '../ast/css.dart';
import '../ast/selector.dart'; import '../ast/selector.dart';
import '../color_names.dart';
import '../exception.dart'; import '../exception.dart';
import '../util/character.dart'; import '../util/character.dart';
import '../util/number.dart'; import '../util/number.dart';
@ -280,8 +281,11 @@ class _SerializeCssVisitor
void visitBoolean(SassBoolean value) => _buffer.write(value.value.toString()); void visitBoolean(SassBoolean value) => _buffer.write(value.value.toString());
void visitColor(SassColor value) { void visitColor(SassColor value) {
// TODO(nweiz): Use color names for named colors. if (value.original != null) {
if (value.alpha == 1) { _buffer.write(value.original);
} else if (namesByColor.containsKey(value)) {
_buffer.write(namesByColor[value]);
} else if (value.alpha == 1) {
_buffer.writeCharCode($hash); _buffer.writeCharCode($hash);
_writeHexComponent(value.red); _writeHexComponent(value.red);
_writeHexComponent(value.green); _writeHexComponent(value.green);

View File

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