mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-27 04:34:59 +01:00
Allow var() in place of multiple arguments to color functions (#208)
See sass/sass#2440
This commit is contained in:
parent
00cb5532a0
commit
aa3c765b10
@ -5,6 +5,9 @@
|
|||||||
* `round()` now returns the correct results for negative numbers that should
|
* `round()` now returns the correct results for negative numbers that should
|
||||||
round down.
|
round down.
|
||||||
|
|
||||||
|
* `var()` may now be passed in place of multiple arguments to `rgb()`, `rgba()`,
|
||||||
|
`hsl()` and `hsla()`.
|
||||||
|
|
||||||
## 1.0.0-beta.4
|
## 1.0.0-beta.4
|
||||||
|
|
||||||
* Support unquoted imports in the indented syntax.
|
* Support unquoted imports in the indented syntax.
|
||||||
|
@ -43,21 +43,39 @@ final List<BuiltInCallable> coreFunctions = new UnmodifiableListView([
|
|||||||
// ## Colors
|
// ## Colors
|
||||||
// ### RGB
|
// ### RGB
|
||||||
|
|
||||||
new BuiltInCallable("rgb", r"$red, $green, $blue", (arguments) {
|
new BuiltInCallable.overloaded("rgb", {
|
||||||
if (arguments[0].isSpecialNumber ||
|
r"$red, $green, $blue": (arguments) {
|
||||||
arguments[1].isSpecialNumber ||
|
if (arguments[0].isSpecialNumber ||
|
||||||
arguments[2].isSpecialNumber) {
|
arguments[1].isSpecialNumber ||
|
||||||
return _functionString('rgb', arguments);
|
arguments[2].isSpecialNumber) {
|
||||||
|
return _functionString('rgb', arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var red = arguments[0].assertNumber("red");
|
||||||
|
var green = arguments[1].assertNumber("green");
|
||||||
|
var blue = arguments[2].assertNumber("blue");
|
||||||
|
|
||||||
|
return new SassColor.rgb(
|
||||||
|
fuzzyRound(_percentageOrUnitless(red, 255, "red")),
|
||||||
|
fuzzyRound(_percentageOrUnitless(green, 255, "green")),
|
||||||
|
fuzzyRound(_percentageOrUnitless(blue, 255, "blue")));
|
||||||
|
},
|
||||||
|
r"$red, $green": (arguments) {
|
||||||
|
// rgb(123, var(--foo)) is valid CSS because --foo might be `456, 789` and
|
||||||
|
// functions are parsed after variable substitution.
|
||||||
|
if (arguments[0].isVar || arguments[1].isVar) {
|
||||||
|
return _functionString('rgb', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $blue.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r"$red": (arguments) {
|
||||||
|
if (arguments.first.isVar) {
|
||||||
|
return _functionString('rgb', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $green.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var red = arguments[0].assertNumber("red");
|
|
||||||
var green = arguments[1].assertNumber("green");
|
|
||||||
var blue = arguments[2].assertNumber("blue");
|
|
||||||
|
|
||||||
return new SassColor.rgb(
|
|
||||||
fuzzyRound(_percentageOrUnitless(red, 255, "red")),
|
|
||||||
fuzzyRound(_percentageOrUnitless(green, 255, "green")),
|
|
||||||
fuzzyRound(_percentageOrUnitless(blue, 255, "blue")));
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new BuiltInCallable.overloaded("rgba", {
|
new BuiltInCallable.overloaded("rgba", {
|
||||||
@ -81,16 +99,43 @@ final List<BuiltInCallable> coreFunctions = new UnmodifiableListView([
|
|||||||
_percentageOrUnitless(alpha, 1, "alpha"));
|
_percentageOrUnitless(alpha, 1, "alpha"));
|
||||||
},
|
},
|
||||||
r"$color, $alpha": (arguments) {
|
r"$color, $alpha": (arguments) {
|
||||||
var color = arguments[0].assertColor("color");
|
// rgba(var(--foo), 0.5) is valid CSS because --foo might be `123, 456,
|
||||||
|
// 789` and functions are parsed after variable substitution.
|
||||||
if (arguments[1].isSpecialNumber) {
|
if (arguments[0].isVar) {
|
||||||
|
return _functionString('rgba', arguments);
|
||||||
|
} else if (arguments[1].isVar) {
|
||||||
|
var first = arguments[0];
|
||||||
|
if (first is SassColor) {
|
||||||
|
return new SassString(
|
||||||
|
"rgba(${first.red}, ${first.green}, ${first.blue}, "
|
||||||
|
"${arguments[1].toCssString()})");
|
||||||
|
} else {
|
||||||
|
return _functionString('rgba', arguments);
|
||||||
|
}
|
||||||
|
} else if (arguments[1].isSpecialNumber) {
|
||||||
|
var color = arguments[0].assertColor("color");
|
||||||
return new SassString(
|
return new SassString(
|
||||||
"rgba(${color.red}, ${color.green}, ${color.blue}, "
|
"rgba(${color.red}, ${color.green}, ${color.blue}, "
|
||||||
"${arguments[1].toCssString()})");
|
"${arguments[1].toCssString()})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var color = arguments[0].assertColor("color");
|
||||||
var alpha = arguments[1].assertNumber("alpha");
|
var alpha = arguments[1].assertNumber("alpha");
|
||||||
return color.changeAlpha(_percentageOrUnitless(alpha, 1, "alpha"));
|
return color.changeAlpha(_percentageOrUnitless(alpha, 1, "alpha"));
|
||||||
|
},
|
||||||
|
r"$red, $green, $blue": (arguments) {
|
||||||
|
if (arguments[0].isVar || arguments[1].isVar || arguments[2].isVar) {
|
||||||
|
return _functionString('rgba', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $alpha.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r"$red": (arguments) {
|
||||||
|
if (arguments.first.isVar) {
|
||||||
|
return _functionString('rgba', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $green.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
@ -115,36 +160,78 @@ final List<BuiltInCallable> coreFunctions = new UnmodifiableListView([
|
|||||||
|
|
||||||
// ### HSL
|
// ### HSL
|
||||||
|
|
||||||
new BuiltInCallable("hsl", r"$hue, $saturation, $lightness", (arguments) {
|
new BuiltInCallable.overloaded("hsl", {
|
||||||
if (arguments[0].isSpecialNumber ||
|
r"$hue, $saturation, $lightness": (arguments) {
|
||||||
arguments[1].isSpecialNumber ||
|
if (arguments[0].isSpecialNumber ||
|
||||||
arguments[2].isSpecialNumber) {
|
arguments[1].isSpecialNumber ||
|
||||||
return _functionString("hsl", arguments);
|
arguments[2].isSpecialNumber) {
|
||||||
|
return _functionString("hsl", arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hue = arguments[0].assertNumber("hue");
|
||||||
|
var saturation = arguments[1].assertNumber("saturation");
|
||||||
|
var lightness = arguments[2].assertNumber("lightness");
|
||||||
|
|
||||||
|
return new SassColor.hsl(hue.value, saturation.value, lightness.value);
|
||||||
|
},
|
||||||
|
r"$hue, $saturation": (arguments) {
|
||||||
|
// hsl(123, var(--foo)) is valid CSS because --foo might be `10%, 20%` and
|
||||||
|
// functions are parsed after variable substitution.
|
||||||
|
if (arguments[0].isVar || arguments[1].isVar) {
|
||||||
|
return _functionString('hsl', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $lightness.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r"$hue": (arguments) {
|
||||||
|
if (arguments.first.isVar) {
|
||||||
|
return _functionString('hsl', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $saturation.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hue = arguments[0].assertNumber("hue");
|
|
||||||
var saturation = arguments[1].assertNumber("saturation");
|
|
||||||
var lightness = arguments[2].assertNumber("lightness");
|
|
||||||
|
|
||||||
return new SassColor.hsl(hue.value, saturation.value, lightness.value);
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new BuiltInCallable("hsla", r"$hue, $saturation, $lightness, $alpha",
|
new BuiltInCallable.overloaded("hsla", {
|
||||||
(arguments) {
|
r"$hue, $saturation, $lightness, $alpha": (arguments) {
|
||||||
if (arguments[0].isSpecialNumber ||
|
if (arguments[0].isSpecialNumber ||
|
||||||
arguments[1].isSpecialNumber ||
|
arguments[1].isSpecialNumber ||
|
||||||
arguments[2].isSpecialNumber ||
|
arguments[2].isSpecialNumber ||
|
||||||
arguments[3].isSpecialNumber) {
|
arguments[3].isSpecialNumber) {
|
||||||
return _functionString("hsla", arguments);
|
return _functionString("hsla", arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
var hue = arguments[0].assertNumber("hue");
|
||||||
|
var saturation = arguments[1].assertNumber("saturation");
|
||||||
|
var lightness = arguments[2].assertNumber("lightness");
|
||||||
|
var alpha = arguments[3].assertNumber("alpha");
|
||||||
|
|
||||||
|
return new SassColor.hsl(hue.value, saturation.value, lightness.value,
|
||||||
|
_percentageOrUnitless(alpha, 1, "alpha"));
|
||||||
|
},
|
||||||
|
r"$hue, $saturation, $lightness": (arguments) {
|
||||||
|
// hsla(123, var(--foo)) is valid CSS because --foo might be `10%, 20%,
|
||||||
|
// 0.5` and functions are parsed after variable substitution.
|
||||||
|
if (arguments[0].isVar || arguments[1].isVar || arguments[2].isVar) {
|
||||||
|
return _functionString('hsla', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $alpha.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r"$hue, $saturation": (arguments) {
|
||||||
|
if (arguments[0].isVar || arguments[1].isVar) {
|
||||||
|
return _functionString('hsla', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $lightness.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
r"$hue": (arguments) {
|
||||||
|
if (arguments.first.isVar) {
|
||||||
|
return _functionString('hsla', arguments);
|
||||||
|
} else {
|
||||||
|
throw new SassScriptException(r"Missing argument $saturation.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var hue = arguments[0].assertNumber("hue");
|
|
||||||
var saturation = arguments[1].assertNumber("saturation");
|
|
||||||
var lightness = arguments[2].assertNumber("lightness");
|
|
||||||
var alpha = arguments[3].assertNumber("alpha");
|
|
||||||
|
|
||||||
return new SassColor.hsl(hue.value, saturation.value, lightness.value,
|
|
||||||
_percentageOrUnitless(alpha, 1, "alpha"));
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
new BuiltInCallable(
|
new BuiltInCallable(
|
||||||
|
@ -53,13 +53,20 @@ abstract class Value {
|
|||||||
/// and all other values count as single-value lists.
|
/// and all other values count as single-value lists.
|
||||||
List<Value> get asList => [this];
|
List<Value> get asList => [this];
|
||||||
|
|
||||||
/// Whether this is a value that CSS may treate as a number, such as `calc()`
|
/// Whether this is a value that CSS may treat as a number, such as `calc()`
|
||||||
/// or `var()`.
|
/// or `var()`.
|
||||||
///
|
///
|
||||||
/// Functions that shadow plain CSS functions need to gracefully handle when
|
/// Functions that shadow plain CSS functions need to gracefully handle when
|
||||||
/// these arguments are passed in.
|
/// these arguments are passed in.
|
||||||
bool get isSpecialNumber => false;
|
bool get isSpecialNumber => false;
|
||||||
|
|
||||||
|
/// Whether this is a call to `var()`, which may be substituted in CSS for a
|
||||||
|
/// custom property value.
|
||||||
|
///
|
||||||
|
/// Functions that shadow plain CSS functions need to gracefully handle when
|
||||||
|
/// these arguments are passed in.
|
||||||
|
bool get isVar => false;
|
||||||
|
|
||||||
const Value();
|
const Value();
|
||||||
|
|
||||||
/// Calls the appropriate visit method on [visitor].
|
/// Calls the appropriate visit method on [visitor].
|
||||||
|
@ -55,6 +55,16 @@ class SassString extends Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get isVar {
|
||||||
|
if (hasQuotes) return false;
|
||||||
|
if (text.length < "var(--_)".length) return false;
|
||||||
|
|
||||||
|
return equalsLetterIgnoreCase($v, text.codeUnitAt(0)) &&
|
||||||
|
equalsLetterIgnoreCase($a, text.codeUnitAt(1)) &&
|
||||||
|
equalsLetterIgnoreCase($r, text.codeUnitAt(2)) &&
|
||||||
|
text.codeUnitAt(3) == $lparen;
|
||||||
|
}
|
||||||
|
|
||||||
bool get isBlank => !hasQuotes && text.isEmpty;
|
bool get isBlank => !hasQuotes && text.isEmpty;
|
||||||
|
|
||||||
factory SassString.empty({bool quotes: false}) =>
|
factory SassString.empty({bool quotes: false}) =>
|
||||||
|
Loading…
Reference in New Issue
Block a user