use crate::*;
pub fn create_reactive_style_attribute<F>(compute: F) -> AttributeValue
where
F: Fn() -> String + 'static,
{
let attr_signal: Signal<String> = Signal::create(compute());
subscribe_attr_signal(attr_signal, compute);
AttributeValue::Signal(attr_signal)
}
pub fn create_reactive_attr_signal<F>(compute: F) -> AttributeValue
where
F: Fn() -> String + 'static,
{
let attr_signal: Signal<String> =
Signal::create(IntoReactiveString::into_reactive_string(compute()));
subscribe_attr_signal(attr_signal, move || {
IntoReactiveString::into_reactive_string(compute())
});
AttributeValue::Signal(attr_signal)
}
pub fn merge_class_values(values: &[AttributeValue]) -> AttributeValue {
let has_signal: bool = values
.iter()
.any(|value: &AttributeValue| matches!(value, AttributeValue::Signal(_)));
if has_signal {
let owned_values: Vec<AttributeValue> = values.to_vec();
let compute = move || {
let mut result: String = String::new();
for value in &owned_values {
let class_segment: String = match value {
AttributeValue::Css(css_class) => {
css_class.inject_style();
css_class.get_name().to_string()
}
AttributeValue::Text(text_value) => text_value.clone(),
AttributeValue::Signal(signal) => signal.get(),
_ => String::new(),
};
if !class_segment.is_empty() {
if !result.is_empty() {
result.push(' ');
}
result.push_str(&class_segment);
}
}
result
};
let attr_signal: Signal<String> = Signal::create(compute());
subscribe_attr_signal(attr_signal, compute);
AttributeValue::Signal(attr_signal)
} else {
let mut result: String = String::new();
for value in values {
let class_segment: String = match value {
AttributeValue::Css(css_class) => {
css_class.inject_style();
css_class.get_name().to_string()
}
AttributeValue::Text(text_value) => text_value.clone(),
_ => String::new(),
};
if !class_segment.is_empty() {
if !result.is_empty() {
result.push(' ');
}
result.push_str(&class_segment);
}
}
AttributeValue::Text(result)
}
}
pub fn merge_style_values(values: &[AttributeValue]) -> AttributeValue {
let has_signal: bool = values
.iter()
.any(|value: &AttributeValue| matches!(value, AttributeValue::Signal(_)));
if has_signal {
let owned_values: Vec<AttributeValue> = values.to_vec();
let compute = move || {
let mut result: String = String::new();
for value in &owned_values {
let style_segment: String = match value {
AttributeValue::Text(text_value) => text_value.clone(),
AttributeValue::Signal(signal) => signal.get(),
_ => String::new(),
};
if !style_segment.is_empty() {
if !result.is_empty() {
result.push(' ');
}
result.push_str(&style_segment);
}
}
result
};
let attr_signal: Signal<String> = Signal::create(compute());
subscribe_attr_signal(attr_signal, compute);
AttributeValue::Signal(attr_signal)
} else {
let mut result: String = String::new();
for value in values {
let style_segment: String = match value {
AttributeValue::Text(text_value) => text_value.clone(),
_ => String::new(),
};
if !style_segment.is_empty() {
if !result.is_empty() {
result.push(' ');
}
result.push_str(&style_segment);
}
}
AttributeValue::Text(result)
}
}
#[allow(static_mut_refs)]
pub(crate) fn mark_injected_class(class_name: String) -> bool {
unsafe {
if (*INJECTED_CLASSES.get_0().get()).is_none() {
(*INJECTED_CLASSES.get_0().get()) = Some(HashSet::new());
}
(*INJECTED_CLASSES.get_0().get())
.as_mut()
.unwrap_unchecked()
.insert(class_name)
}
}