use crate::*;
impl std::fmt::Debug for View {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("View")
.field("nodes", &self.get_nodes())
.field("cleanups", &format!("{} cleanups", self.get_cleanups().len()))
.finish()
}
}
impl std::fmt::Debug for NodeView {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("NodeView")
.field("node", &self.get_node())
.field("cleanups", &format!("{} cleanups", self.get_cleanups().len()))
.finish()
}
}
impl View {
pub fn empty() -> Self {
View {
nodes: Vec::new(),
cleanups: Vec::new(),
}
}
pub fn from_node(node: Node) -> Self {
View {
nodes: vec![node],
cleanups: Vec::new(),
}
}
pub fn from_nodes(nodes: Vec<Node>) -> Self {
View {
nodes,
cleanups: Vec::new(),
}
}
pub fn append_to(&self, parent: &Element) {
for node in self.get_nodes() {
let _ = parent.append_child(node);
}
}
pub fn insert_before_ref(&self, ref_node: &Node) {
if let Some(parent) = ref_node.parent_node() {
for node in self.get_nodes() {
let _ = parent.insert_before(node, Some(ref_node));
}
}
}
pub fn remove(&mut self) {
for node in self.get_nodes() {
if let Some(parent) = node.parent_node() {
let _ = parent.remove_child(node);
}
}
for cleanup in self.get_mut_cleanups().drain(..) {
cleanup();
}
}
pub fn dispose(&mut self) {
for cleanup in self.get_mut_cleanups().drain(..) {
cleanup();
}
}
pub fn first_node(&self) -> Option<&Node> {
self.get_nodes().first()
}
pub fn is_empty(&self) -> bool {
self.get_nodes().is_empty()
}
pub fn merge(&mut self, other: View) {
self.get_mut_nodes().extend(other.get_nodes().clone());
self.get_mut_cleanups().extend(other.get_cleanups().clone());
}
pub fn node_refs(&self) -> View {
View {
nodes: self.get_nodes().clone(),
cleanups: Vec::new(),
}
}
pub fn into_node_view(mut self) -> NodeView {
let node: Node = self.get_mut_nodes().remove(0);
NodeView {
node,
cleanups: std::mem::take(self.get_mut_cleanups()),
}
}
}
impl NodeView {
pub fn from_node(node: Node) -> Self {
NodeView {
node,
cleanups: Vec::new(),
}
}
pub fn into_view(self) -> View {
View {
nodes: vec![self.get_node().clone()],
cleanups: self.get_cleanups().clone(),
}
}
}
impl IntoView for View {
fn into_view(self) -> View {
self
}
}
impl IntoView for NodeView {
fn into_view(self) -> View {
self.into_view()
}
}
impl IntoView for Element {
fn into_view(self) -> View {
View::from_node(self.into())
}
}
impl IntoView for String {
fn into_view(self) -> View {
let document: Document = window().unwrap().document().unwrap();
let text: Text = document.create_text_node(&self);
View::from_node(text.into())
}
}
impl IntoView for &str {
fn into_view(self) -> View {
self.to_string().into_view()
}
}
impl IntoView for i32 {
fn into_view(self) -> View {
self.to_string().into_view()
}
}
impl IntoView for usize {
fn into_view(self) -> View {
self.to_string().into_view()
}
}
impl IntoView for f64 {
fn into_view(self) -> View {
self.to_string().into_view()
}
}
impl IntoView for bool {
fn into_view(self) -> View {
self.to_string().into_view()
}
}
impl<T> IntoView for Signal<T>
where
T: Clone + PartialEq + std::fmt::Display + 'static,
{
fn into_view(self) -> View {
let document: Document = window().unwrap().document().unwrap();
let initial: String = self.get_untracked().to_string();
let text: Text = document.create_text_node(&initial);
let text_clone: Text = text.clone();
let signal_inner: Signal<T> = self;
signal_inner.replace_subscribe(move || {
let new_value: String = signal_inner.get_untracked().to_string();
text_clone.set_text_content(Some(&new_value));
});
View::from_node(text.into())
}
}