use std::cell::RefCell;
use std::rc::Rc;
use tairitsu_vdom::Platform;
use super::{CssProperty, Property, StyleStringBuilder};
pub struct StyleBuilder<'a, P: Platform> {
platform: &'a Rc<RefCell<P>>,
element: &'a P::Element,
properties: Vec<(Property, String)>,
}
impl<'a, P: Platform> Clone for StyleBuilder<'a, P> {
fn clone(&self) -> Self {
Self {
platform: self.platform,
element: self.element,
properties: self.properties.clone(),
}
}
}
impl<'a, P: Platform> StyleBuilder<'a, P> {
pub fn new(platform: &'a Rc<RefCell<P>>, element: &'a P::Element) -> Self {
Self {
platform,
element,
properties: Vec::new(),
}
}
pub fn add(mut self, property: CssProperty, value: &str) -> Self {
self.properties
.push((Property::Known(property), value.to_string()));
self
}
pub fn add_custom(mut self, property: &str, value: &str) -> Self {
self.properties
.push((Property::Custom(property.to_string()), value.to_string()));
self
}
pub fn add_px(mut self, property: CssProperty, pixels: u32) -> Self {
self.properties
.push((Property::Known(property), format!("{}px", pixels)));
self
}
pub fn add_all(mut self, properties: &[(CssProperty, &str)]) -> Self {
for &(property, value) in properties {
self.properties
.push((Property::Known(property), value.to_string()));
}
self
}
pub fn apply(self) {
if self.properties.is_empty() {
return;
}
for (property, value) in self.properties {
self.platform
.borrow_mut()
.set_style(self.element, property.as_str(), &value);
}
}
pub fn build_string<F>(f: F) -> String
where
F: FnOnce(StyleStringBuilder) -> StyleStringBuilder,
{
f(StyleStringBuilder::new()).build()
}
pub fn build_clean<F>(f: F) -> String
where
F: FnOnce(StyleStringBuilder) -> StyleStringBuilder,
{
f(StyleStringBuilder::new()).build_clean()
}
}
#[derive(Debug, Clone)]
enum AttributeValue {
String(String),
Bool(bool),
}
pub struct AttributeBuilder<'a, P: Platform> {
platform: &'a Rc<RefCell<P>>,
element: &'a P::Element,
attributes: Vec<(String, AttributeValue)>,
}
impl<'a, P: Platform> Clone for AttributeBuilder<'a, P> {
fn clone(&self) -> Self {
Self {
platform: self.platform,
element: self.element,
attributes: self.attributes.clone(),
}
}
}
impl<'a, P: Platform> AttributeBuilder<'a, P> {
pub fn new(platform: &'a Rc<RefCell<P>>, element: &'a P::Element) -> Self {
Self {
platform,
element,
attributes: Vec::new(),
}
}
pub fn add(mut self, name: &str, value: &str) -> Self {
self.attributes
.push((name.to_string(), AttributeValue::String(value.to_string())));
self
}
pub fn add_bool(mut self, name: &str, value: bool) -> Self {
self.attributes
.push((name.to_string(), AttributeValue::Bool(value)));
self
}
pub fn add_data(self, name: &str, value: &str) -> Self {
self.add(&format!("data-{}", name), value)
}
pub fn apply(self) {
if self.attributes.is_empty() {
return;
}
for (name, value) in self.attributes {
match value {
AttributeValue::String(v) => {
self.platform
.borrow_mut()
.set_attribute(self.element, &name, &v);
}
AttributeValue::Bool(v) => {
if v {
self.platform
.borrow_mut()
.set_attribute(self.element, &name, "");
} else {
self.platform
.borrow_mut()
.remove_attribute(self.element, &name);
}
}
}
}
}
}