simplify declaration of other color fns

This commit is contained in:
ConnorSkees 2020-04-30 18:59:27 -04:00
parent 11e0d523b2
commit 4cfa29c971

View File

@ -3,8 +3,12 @@ use super::GlobalFunctionMap;
use num_traits::{One, Signed, Zero}; use num_traits::{One, Signed, Zero};
use super::Builtin; use super::Builtin;
use crate::args::CallArgs;
use crate::color::Color; use crate::color::Color;
use crate::common::QuoteKind; use crate::common::QuoteKind;
use crate::error::SassResult;
use crate::scope::Scope;
use crate::selector::Selector;
use crate::unit::Unit; use crate::unit::Unit;
use crate::value::{Number, Value}; use crate::value::{Number, Value};
@ -51,7 +55,11 @@ macro_rules! opt_hsl {
} }
pub(crate) fn register(f: &mut GlobalFunctionMap) { pub(crate) fn register(f: &mut GlobalFunctionMap) {
f.insert("change-color", Builtin::new(|mut args, scope, super_selector| { fn change_color(
mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
if args.get_positional(1, scope, super_selector).is_some() { if args.get_positional(1, scope, super_selector).is_some() {
return Err( return Err(
("Only one positional argument is allowed. All other arguments must be passed by name.", args.span() ("Only one positional argument is allowed. All other arguments must be passed by name.", args.span()
@ -60,9 +68,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
v => return Err( v => {
(format!("$color: {} is not a color.", v.to_css_string(args.span())?), args.span() return Err((
).into()), format!("$color: {} is not a color.", v.to_css_string(args.span())?),
args.span(),
)
.into())
}
}; };
opt_rgba!(args, alpha, "alpha", 0, 1, scope, super_selector); opt_rgba!(args, alpha, "alpha", 0, 1, scope, super_selector);
@ -71,24 +83,46 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
opt_rgba!(args, blue, "blue", 0, 255, scope, super_selector); opt_rgba!(args, blue, "blue", 0, 255, scope, super_selector);
if red.is_some() || green.is_some() || blue.is_some() { if red.is_some() || green.is_some() || blue.is_some() {
return Ok(Value::Color(Box::new(Color::from_rgba(red.unwrap_or(color.red()), green.unwrap_or(color.green()), blue.unwrap_or(color.blue()), alpha.unwrap_or(color.alpha()))))) return Ok(Value::Color(Box::new(Color::from_rgba(
red.unwrap_or(color.red()),
green.unwrap_or(color.green()),
blue.unwrap_or(color.blue()),
alpha.unwrap_or(color.alpha()),
))));
} }
let hue = match named_arg!(args, scope, super_selector, "hue"=Value::Null) { let hue = match named_arg!(args, scope, super_selector, "hue" = Value::Null) {
Value::Dimension(n, _) => Some(n), Value::Dimension(n, _) => Some(n),
Value::Null => None, Value::Null => None,
v => return Err( v => {
(format!("$hue: {} is not a number.", v.to_css_string(args.span())?), args.span() return Err((
).into()), format!("$hue: {} is not a number.", v.to_css_string(args.span())?),
args.span(),
)
.into())
}
}; };
opt_hsl!(args, saturation, "saturation", 0, 100, scope, super_selector); opt_hsl!(
args,
saturation,
"saturation",
0,
100,
scope,
super_selector
);
opt_hsl!(args, luminance, "lightness", 0, 100, scope, super_selector); opt_hsl!(args, luminance, "lightness", 0, 100, scope, super_selector);
if hue.is_some() || saturation.is_some() || luminance.is_some() { if hue.is_some() || saturation.is_some() || luminance.is_some() {
// Color::as_hsla() returns more exact values than Color::hue(), etc. // Color::as_hsla() returns more exact values than Color::hue(), etc.
let (this_hue, this_saturation, this_luminance, this_alpha) = color.as_hsla(); let (this_hue, this_saturation, this_luminance, this_alpha) = color.as_hsla();
return Ok(Value::Color(Box::new(Color::from_hsla(hue.unwrap_or(this_hue), saturation.unwrap_or(this_saturation), luminance.unwrap_or(this_luminance), alpha.unwrap_or(this_alpha))))) return Ok(Value::Color(Box::new(Color::from_hsla(
hue.unwrap_or(this_hue),
saturation.unwrap_or(this_saturation),
luminance.unwrap_or(this_luminance),
alpha.unwrap_or(this_alpha),
))));
} }
Ok(Value::Color(if let Some(a) = alpha { Ok(Value::Color(if let Some(a) = alpha {
@ -96,10 +130,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
})); }
f.insert(
"adjust-color", fn adjust_color(
Builtin::new(|mut args, scope, super_selector| { mut args: CallArgs,
scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
v => { v => {
@ -173,17 +210,30 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
}), }
);
f.insert( fn scale_color(
"scale-color", mut args: CallArgs,
Builtin::new(|mut args, scope, super_selector| { scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
fn scale(val: Number, by: Number, max: Number) -> Number {
if by.is_zero() {
return val;
}
val.clone() + (if by.is_positive() { max - val } else { val }) * by
}
let span = args.span(); let span = args.span();
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
v => return Err( v => {
(format!("$color: {} is not a color.", v.to_css_string(span)?), span return Err((
).into()), format!("$color: {} is not a color.", v.to_css_string(span)?),
span,
)
.into())
}
}; };
macro_rules! opt_scale_arg { macro_rules! opt_scale_arg {
@ -193,14 +243,28 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
Some(bound!($args, $arg, n, Unit::Percent, $low, $high) / Number::from(100)) Some(bound!($args, $arg, n, Unit::Percent, $low, $high) / Number::from(100))
} }
v @ Value::Dimension(..) => { v @ Value::Dimension(..) => {
return Err( return Err((
(format!("${}: Expected {} to have unit \"%\".", $arg, v.to_css_string($args.span())?), $args.span()).into() format!(
"${}: Expected {} to have unit \"%\".",
$arg,
v.to_css_string($args.span())?
),
$args.span(),
) )
.into())
} }
Value::Null => None, Value::Null => None,
v => return Err( v => {
(format!("${}: {} is not a number.", $arg, v.to_css_string($args.span())?), $args.span() return Err((
).into()), format!(
"${}: {} is not a number.",
$arg,
v.to_css_string($args.span())?
),
$args.span(),
)
.into())
}
}; };
}; };
} }
@ -235,8 +299,24 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
)))); ))));
} }
opt_scale_arg!(args, saturation, "saturation", -100, 100, scope, super_selector); opt_scale_arg!(
opt_scale_arg!(args, luminance, "lightness", -100, 100, scope, super_selector); args,
saturation,
"saturation",
-100,
100,
scope,
super_selector
);
opt_scale_arg!(
args,
luminance,
"lightness",
-100,
100,
scope,
super_selector
);
if saturation.is_some() || luminance.is_some() { if saturation.is_some() || luminance.is_some() {
// Color::as_hsla() returns more exact values than Color::hue(), etc. // Color::as_hsla() returns more exact values than Color::hue(), etc.
@ -263,11 +343,13 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} else { } else {
color color
})) }))
}), }
);
f.insert( fn ie_hex_str(
"ie-hex-str", mut args: CallArgs,
Builtin::new(|mut args, scope, super_selector| { scope: &Scope,
super_selector: &Selector,
) -> SassResult<Value> {
args.max_args(1)?; args.max_args(1)?;
let color = match arg!(args, scope, super_selector, 0, "color") { let color = match arg!(args, scope, super_selector, 0, "color") {
Value::Color(c) => c, Value::Color(c) => c,
@ -280,13 +362,10 @@ pub(crate) fn register(f: &mut GlobalFunctionMap) {
} }
}; };
Ok(Value::Ident(color.to_ie_hex_str(), QuoteKind::None)) Ok(Value::Ident(color.to_ie_hex_str(), QuoteKind::None))
}),
);
}
fn scale(val: Number, by: Number, max: Number) -> Number {
if by.is_zero() {
return val;
} }
val.clone() + (if by.is_positive() { max - val } else { val }) * by
f.insert("change-color", Builtin::new(change_color));
f.insert("adjust-color", Builtin::new(adjust_color));
f.insert("scale-color", Builtin::new(scale_color));
f.insert("ie-hex-str", Builtin::new(ie_hex_str));
} }