use std::borrow::Cow;
use std::cell::RefCell;
use std::ops::DerefMut;
#[derive(Default, PartialEq)]
pub struct SpecialAttributes {
on_create_element: Option<KeyAndElementFn>,
on_remove_element: Option<KeyAndElementFn>,
pub dangerous_inner_html: Option<String>,
}
impl SpecialAttributes {
pub fn on_create_element_key(&self) -> Option<&Cow<'static, str>> {
self.on_create_element.as_ref().map(|k| &k.key)
}
pub fn set_on_create_element<Key, Func>(&mut self, key: Key, func: Func)
where
Key: Into<Cow<'static, str>>,
Func: FnMut(web_sys::Element) + 'static,
{
self.on_create_element = Some(KeyAndElementFn {
key: key.into(),
func: RefCell::new(ElementFunc::OneArg(Box::new(func))),
});
}
#[doc(hidden)]
pub fn set_on_create_element_no_args<Key, Func>(&mut self, key: Key, func: Func)
where
Key: Into<Cow<'static, str>>,
Func: FnMut() + 'static,
{
self.on_create_element = Some(KeyAndElementFn {
key: key.into(),
func: RefCell::new(ElementFunc::NoArgs(Box::new(func))),
});
}
pub fn maybe_call_on_create_element(&self, element: &web_sys::Element) {
if let Some(on_create_elem) = &self.on_create_element {
on_create_elem.call(element.clone());
}
let _ = element;
}
}
impl SpecialAttributes {
pub fn on_remove_element_key(&self) -> Option<&Cow<'static, str>> {
self.on_remove_element.as_ref().map(|k| &k.key)
}
pub fn set_on_remove_element<Key, Func>(&mut self, key: Key, func: Func)
where
Key: Into<Cow<'static, str>>,
Func: FnMut(web_sys::Element) + 'static,
{
self.on_remove_element = Some(KeyAndElementFn {
key: key.into(),
func: RefCell::new(ElementFunc::OneArg(Box::new(func))),
});
}
#[doc(hidden)]
pub fn set_on_remove_element_no_args<Key, Func>(&mut self, key: Key, func: Func)
where
Key: Into<Cow<'static, str>>,
Func: FnMut() + 'static,
{
self.on_remove_element = Some(KeyAndElementFn {
key: key.into(),
func: RefCell::new(ElementFunc::NoArgs(Box::new(func))),
});
}
pub fn maybe_call_on_remove_element(&self, element: &web_sys::Element) {
if let Some(on_remove_elem) = &self.on_remove_element {
on_remove_elem.call(element.clone());
}
let _ = element;
}
}
struct KeyAndElementFn {
key: Cow<'static, str>,
func: RefCell<ElementFunc>,
}
enum ElementFunc {
NoArgs(Box<dyn FnMut()>),
OneArg(Box<dyn FnMut(web_sys::Element)>),
}
impl KeyAndElementFn {
fn call(&self, element: web_sys::Element) {
match self.func.borrow_mut().deref_mut() {
ElementFunc::NoArgs(func) => (func)(),
ElementFunc::OneArg(func) => (func)(element),
};
}
}
impl PartialEq for KeyAndElementFn {
fn eq(&self, rhs: &Self) -> bool {
self.key == rhs.key
}
}