Implement one and two args for rgba()

This commit is contained in:
ConnorSkees 2020-02-14 11:52:31 -05:00
parent a2ddc8016f
commit 08bfa8f145
5 changed files with 66 additions and 5 deletions

View File

@ -32,6 +32,10 @@ impl CallArgs {
pub fn get(&self, val: &str) -> Option<&Value> {
self.0.get(val)
}
pub fn len(&self) -> usize {
self.0.len()
}
}
pub(crate) fn eat_func_args<I: Iterator<Item = Token>>(

View File

@ -36,8 +36,49 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
}
});
decl!(f "rgba", |args, _| {
let channels = args.get("channels").unwrap_or(&Value::Null);
if channels.is_null() {
if args.len() == 1 {
let mut channels = match arg!(args, 0, "channels").eval() {
Value::List(v, _) => v,
_ => todo!("missing element $green")
};
assert_eq!(channels.len(), 3usize);
let blue = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100),
_ => todo!("$blue: ___ is not a color")
};
let green = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100),
_ => todo!("$green: ___ is not a color")
};
let red = match channels.pop() {
Some(Value::Dimension(n, Unit::None)) => n,
Some(Value::Dimension(n, Unit::Percent)) => n / Number::from(100),
_ => todo!("$red: ___ is not a color")
};
let color = Color::from_rgba(red, green, blue, Number::from(1));
Some(Value::Color(color))
} else if args.len() == 2 {
let color = match arg!(args, 0, "color").eval() {
Value::Color(c) => c,
_ => todo!("expected color")
};
let alpha = match arg!(args, 1, "alpha").eval() {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
_ => todo!("expected either unitless or % number for alpha"),
};
Some(Value::Color(color.with_alpha(alpha)))
} else {
let red = match arg!(args, 0, "red").eval() {
Value::Dimension(n, Unit::None) => n,
Value::Dimension(n, Unit::Percent) => (n / Number::from(100)) * Number::from(255),
@ -59,8 +100,6 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
_ => todo!("expected either unitless or % number for alpha"),
};
Some(Value::Color(Color::from_rgba(red, green, blue, alpha)))
} else {
todo!("channels variable in `rgba`")
}
});
decl!(f "hsl", |args, _| {

View File

@ -171,6 +171,10 @@ impl Color {
self.alpha.clone()
}
pub fn with_alpha(self, alpha: Number) -> Self {
Color::from_rgba(self.red, self.green, self.blue, alpha)
}
/// Makes a color more opaque.
/// Takes a color and a number between 0 and 1,
/// and returns a color with the opacity increased by that amount.

View File

@ -276,7 +276,9 @@ impl<'a> SelectorParser<'a> {
}
if let Some(Token { kind, .. }) = tokens.next() {
match kind {
TokenKind::Ident(v) | TokenKind::Number(v) => self.selectors.push(SelectorKind::Element(v)),
TokenKind::Ident(v) | TokenKind::Number(v) => {
self.selectors.push(SelectorKind::Element(v))
}
TokenKind::Symbol(Symbol::Period) => self.selectors.push(SelectorKind::Class),
TokenKind::Symbol(Symbol::Hash) => self.selectors.push(SelectorKind::Id),
TokenKind::Symbol(Symbol::Colon) => self.consume_pseudo_selector(tokens),

View File

@ -81,6 +81,18 @@ test!(
opacity_function_number_unit,
"a {\n color: opacity(1px);\n}\n"
);
// blocked on better function-call argument parsing
// specifically, passing lists as values
// test!(
// rgba_one_arg,
// "a {\n color: rgba(1 2 3);;\n}\n",
// "a {\n color: #010203;\n}\n"
// );
test!(
rgba_two_args,
"a {\n color: rgba(red, 0.5);\n}\n",
"a {\n color: rgba(255, 0, 0, 0.5);\n}\n"
);
test!(
rgba_opacity_over_1,
"a {\n color: rgba(1, 2, 3, 3);\n}\n",