anansi_aux/
lib.rs

1use std::fmt;
2use std::any::Any;
3use std::rc::Rc;
4use std::slice::{Iter, IterMut};
5use std::cell::{RefCell, Ref, RefMut};
6use std::collections::{HashMap, HashSet};
7use std::error::Error;
8use std::marker::PhantomData;
9
10use wasm_bindgen::prelude::*;
11use wasm_bindgen::JsCast;
12use wasm_bindgen::closure::Closure;
13use web_sys::{Element, Node, NodeList, Document, Text, Window, Event};
14
15use serde_json::Value;
16use serde::{Serialize, Serializer, ser::SerializeSeq, Deserialize, de::DeserializeOwned};
17use serde::de::{Deserializer, Visitor, SeqAccess};
18
19pub use anansi_macros::*;
20
21extern crate self as anansi_aux;
22
23pub mod prelude {
24    pub use serde_json::Value;
25    pub use serde::{Serialize, Deserialize};
26    pub use anansi_macros::{store, Properties, component, function_component, refchild, release};
27    pub use super::{attributes, element, document, Rsx, Sub, Proxy, Comp, Elem, Attribute, CbCmd, Resource, Rendered, RefVec, RefChild, Signal};
28}
29
30pub mod components;
31
32pub type Mounts = &'static [(&'static str, fn(String), fn())];
33
34thread_local! {
35    pub static WINDOW: Window = web_sys::window().expect("should have a window");
36    pub static DOCUMENT: Document = {
37        let window = web_sys::window().expect("should have a window");
38        window.document().expect("window should have a document")
39    };
40    pub static CALLBACKS: RefCell<HashMap<String, CallbackData>> = RefCell::new(HashMap::new());
41    pub static RECALLS: RefCell<HashMap<String, RecallData>> = RefCell::new(HashMap::new());
42    pub static APP_STATE: RefCell<Option<AppState>> = RefCell::new(None);
43    pub static NODE_ID: RefCell<String> = RefCell::new(String::new());
44    pub static IDS: RefCell<Vec<String>> = RefCell::new(vec![]);
45    pub static RID: RefCell<usize> = RefCell::new(0);
46    pub static CTX: RefCell<HashMap<String, Ctx>> = RefCell::new(HashMap::new());
47    pub static REFS: RefCell<HashMap<usize, Vec<usize>>> = RefCell::new(HashMap::new());
48    pub static COMP_RSX: RefCell<HashMap<CompId, Option<Rsx>>> = RefCell::new(HashMap::new());
49    pub static VNODE_MAP: RefCell<HashMap<String, Node>> = RefCell::new(HashMap::new());
50    pub static MOUNTED: RefCell<HashSet<String>> = RefCell::new(HashSet::new());
51    pub static VIRT_NODES: RefCell<HashMap<String, Rsx>> = RefCell::new(HashMap::new());
52    pub static EVENT_CB: RefCell<HashMap<&'static str, Closure<dyn Fn(Event)>>> = RefCell::new(HashMap::new());
53}
54
55#[derive(PartialEq, Eq, Hash, Debug)]
56pub struct CompId {
57    node_id: String,
58    n: usize,
59}
60
61impl CompId {
62    pub fn new(node_id: String, n: usize) -> Self {
63        Self {node_id, n}
64    }
65    pub fn node_id(&self) -> &String {
66        &self.node_id
67    }
68    pub fn n(&self) -> usize {
69        self.n
70    }
71}
72
73#[macro_export]
74macro_rules! document {
75    ($e:expr) => {
76        anansi_aux::DOCUMENT.with($e)
77    }
78}
79
80#[macro_export]
81macro_rules! comp_statics {
82    ($($name:expr,)*) => {
83        pub static STATICS: &[(&'static str, &'static [u8])] = &[
84            $((concat!("/static/styles/", $name, ".css"), include_bytes!(concat!("static", anansi_aux::main_separator!(), "styles", anansi_aux::main_separator!(), $name, ".css"))),)*
85        ];
86    }
87}
88
89#[macro_export]
90#[cfg(not(target_os = "windows"))]
91macro_rules! main_separator {
92    () => {r"/"}
93}
94
95#[macro_export]
96#[cfg(target_os = "windows")]
97macro_rules! main_separator {
98    () => {r"\"}
99}
100
101pub fn box_closure<F: Fn(Event) + 'static>(closure: F) -> Box<dyn Fn(Event)> {
102    Box::new(closure)
103}
104
105pub fn load_style(url: &'static str) {
106    DOCUMENT.with(|document| {
107        if let Ok(links) = document.query_selector_all("link") {
108            for i in 0..links.length() {
109                if let Some(node) = links.get(i) {
110                    let link = node.dyn_ref::<Element>().unwrap();
111                    if let Some(href) = link.attributes().get_named_item("href") {
112                        if href.value() == url {
113                            return;
114                        }
115                    }
116                }
117            }
118        }
119        if let Ok(head) = document.query_selector("head") {
120            if let Some(head) = head {
121                if let Ok(link) = document.create_element("link") {
122                    link.set_attribute("rel", "stylesheet").unwrap();
123                    link.set_attribute("href", url).unwrap();
124                    head.append_child(&link).unwrap();
125                }
126            }
127        }
128    });
129}
130
131#[derive(Debug)]
132pub enum CbCmd {
133    Callback(u8),
134    Text(u8, Result<String, Box<dyn Error>>),
135}
136
137#[derive(Properties, Serialize, Deserialize)]
138pub struct EmptyProp;
139
140#[derive(Debug)]
141pub enum Resource<D> {
142    Pending,
143    Rejected(Box<dyn Error>),
144    Resolved(D),
145}
146
147pub struct Rendered(Vec<Rsx>);
148
149impl Rendered {
150    pub fn new(rsx: Vec<Rsx>) -> Self {
151        Self(rsx)
152    }
153    pub fn resume(_store: &mut AppState, _n: usize) -> Self {
154        Self(vec![])
155    }
156    pub fn rsx(&self) -> &Vec<Rsx> {
157        &self.0
158    }
159}
160
161pub enum Cmd {
162    Update(Rsx, String),
163    Set(HashMap<String, Ctx>),
164}
165
166pub trait RefChild {
167    type Item;
168    fn new(pos: usize, item: Self::Item) -> Self;
169    fn pos(&self) -> usize;
170    fn pos_mut(&mut self) -> &mut usize;
171}
172
173impl<T: Serialize> Serialize for RefVec<T> {
174    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175    where
176        S: Serializer,
177    {
178        let mut seq = serializer.serialize_seq(Some(self.0.len()))?;
179        for e in &self.0 {
180            seq.serialize_element(&*e.borrow())?;
181        }
182        seq.end()
183    }
184}
185
186struct RefVecVisitor<T> {
187    t: PhantomData<T>,
188}
189
190impl<'de, T: Deserialize<'de> + RefChild> Visitor<'de> for RefVecVisitor<T> {
191    type Value = RefVec<T>;
192
193    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
194        formatter.write_str("struct RefVec")
195    }
196
197    fn visit_seq<V>(self, mut seq: V) -> Result<RefVec<T>, V::Error>
198    where
199        V: SeqAccess<'de>,
200    {
201        let mut new_obj = RefVec::new();
202        while let Some(value) = seq.next_element()? {
203            new_obj.push_ref(value);
204        }
205
206        Ok(new_obj)
207    }
208}
209
210impl<'de, T: Deserialize<'de> + RefChild> Deserialize<'de> for RefVec<T> {
211    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
212    where
213        D: Deserializer<'de>,
214    {
215        deserializer.deserialize_seq(RefVecVisitor {t: PhantomData})
216    }
217}
218
219pub trait Parent {
220    type Item;
221}
222
223#[derive(Debug)]
224pub struct RefVec<T: ?Sized>(Vec<Rc<RefCell<T>>>);
225
226impl<T> Parent for RefVec<T> {
227    type Item = T;
228}
229
230impl<T: ?Sized> RefVec<T> {
231    pub fn new() -> Self {
232        Self(vec![])
233    }
234    pub fn inner(&self) -> &Vec<Rc<RefCell<T>>> {
235        &self.0
236    }
237    pub fn len(&self) -> usize {
238        self.0.len()
239    }
240}
241
242pub trait GetOne {
243    fn get_one(&self, n: usize) -> Rc<dyn Any>;
244}
245
246impl<T: 'static> GetOne for RefVec<T> {
247    fn get_one(&self, n: usize) -> Rc<dyn Any> {
248        self.0[n].clone() as Rc<dyn Any>
249    }
250}
251
252impl<T: RefChild> RefVec<T> {
253    pub fn push(&mut self, t: <T as RefChild>::Item) {
254        self.0.push(Rc::new(RefCell::new(T::new(self.0.len(), t))));
255    }
256    pub fn push_ref(&mut self, t: T) {
257        self.0.push(Rc::new(RefCell::new(t)));
258    }
259    pub fn append(&mut self, t: &mut Vec<<T as RefChild>::Item>) {
260        let v = t.split_off(0);
261        let mut n = self.0.len();
262        for e in v {
263            self.0.push(Rc::new(RefCell::new(T::new(n, e))));
264            n += 1;
265        }
266    }
267    pub fn clear(&mut self) {
268        self.0.clear();
269    }
270    pub fn swap(&mut self, a: usize, b: usize) {
271        {
272            let mut first = self.0[a].borrow_mut();
273            let mut second = self.0[b].borrow_mut();
274            let p = first.pos();
275            *first.pos_mut() = second.pos();
276            *second.pos_mut() = p;
277        }
278        self.0.swap(a, b);
279    }
280    pub fn remove(&mut self, index: usize) -> Rc<RefCell<T>> {
281        let mut rest = self.0.split_off(index + 1);
282        let removed = self.0.pop().unwrap();
283        for c in &mut rest {
284            *c.borrow_mut().pos_mut() -= 1;
285        }
286        self.0.append(&mut rest);
287        removed
288    }
289    pub fn iter(&self) -> RefIter<'_, T> {
290        RefIter {iter: self.0.iter()}
291    }
292    pub fn iter_mut(&mut self) -> RefIterMut<'_, T> {
293        RefIterMut {iter_mut: self.0.iter_mut()}
294    }
295    pub fn with_capacity(capacity: usize) -> Self {
296        Self(Vec::with_capacity(capacity))
297    }
298}
299
300pub struct RefIter<'a, T> {
301    iter: Iter<'a, Rc<RefCell<T>>>,
302}
303
304impl<'a, T> Iterator for RefIter<'a, T> {
305    type Item = Ref<'a, T>;
306    fn next(&mut self) -> Option<Self::Item> {
307        if let Some(r) = self.iter.next() {
308            Some(r.borrow())
309        } else {
310            None
311        }
312    }
313}
314
315pub struct RefIterMut<'a, T> {
316    iter_mut: IterMut<'a, Rc<RefCell<T>>>,
317}
318
319impl<'a, T> Iterator for RefIterMut<'a, T> {
320    type Item = RefMut<'a, T>;
321    fn next(&mut self) -> Option<Self::Item> {
322        if let Some(r) = self.iter_mut.next() {
323            Some(r.borrow_mut())
324        } else {
325            None
326        }
327    }
328}
329
330pub struct Signal<T> {
331    _proxy: SignalProxy,
332    value: T,
333}
334
335impl<T> Parent for Signal<T> {
336    type Item = T;
337}
338
339impl<T: Serialize + DeserializeOwned + 'static + std::fmt::Debug> Signal<T> {
340    pub fn resume(store: &mut AppState, n: usize) -> Self {
341        if let Obj::Js(v) = &store.objs[n] {
342            let t: T = serde_json::from_value(v.clone()).unwrap();
343            let subs = store.subs.pop().expect("problem getting subs");
344            Self {_proxy: SignalProxy::from(subs[0]), value: t}
345        } else {
346            panic!("expected JavaScript value when resuming")
347        }
348    }
349}
350
351impl<T> Signal<T> {
352    pub fn new(t: T) -> Self {
353        Self {_proxy: SignalProxy::new(), value: t}
354    }
355    pub fn value(&mut self) -> &T {
356        self._proxy.set();
357        &self.value
358    }
359    pub fn value_mut(&mut self) -> &mut T {
360        self._proxy._invalid = true;
361        &mut self.value
362    }
363    pub fn get_subs(&self) -> Vec<String> {
364        self._proxy.get_subs()
365    }
366    pub fn into_inner(self) -> T {
367        self.value
368    }
369}
370
371#[derive(Clone)]
372pub struct SignalProxy {
373    pub _learning: bool,
374    pub _invalid: bool,
375    pub _node: u32,
376    pub _dirty: i64,
377    pub _sub: Sub,
378}
379
380impl SignalProxy {
381    pub fn new() -> Self {
382        Self {_learning: false, _invalid: false, _node: 0, _dirty: -1, _sub: (0, 0)}
383    }
384    pub fn from(_sub: (u32, i64)) -> Self {
385        Self {_learning: false, _invalid: false, _node: 0, _dirty: -1, _sub}
386    }
387    pub fn set(&mut self) {
388        if self._learning {
389            self._sub = (self._node, 0);
390        } else {
391            if self._dirty == -1 {
392                self._dirty = 0;
393            }
394            self._dirty |= 1;
395        }
396    }
397    pub fn start_proxy(&mut self) -> Sub {
398        self._learning = true;
399        self._invalid = false;
400        self._dirty = -1;
401        self._sub
402    }
403    pub fn stop_proxy(&mut self, sub: Sub) {
404        self._sub = sub;
405        self._learning = false;
406    }
407    pub fn get_subs(&self) -> Vec<String> {
408        vec![format!("{} {}", self._sub.0, self._sub.1)]
409    }
410}
411
412pub struct Proxy {
413    pub _learning: bool,
414    pub _invalid: bool,
415    pub _node: u32,
416    pub _dirty: i64,
417    pub _subs: Vec<Sub>,
418}
419
420impl Proxy {
421    pub fn new(subs: Vec<Sub>) -> Self {
422        Self {_learning: false, _invalid: false, _node: 0, _dirty: -1, _subs: subs}
423    }
424    pub fn set(&mut self, n: i64) {
425        if self._learning {
426            self._subs.push((self._node, n));
427        } else {
428            if self._dirty == -1 {
429                self._dirty = 0;
430            }
431            self._dirty |= n;
432        }
433    }
434    pub fn start_proxy(&mut self) -> Vec<Sub> {
435        self._learning = true;
436        self._invalid = false;
437        self._dirty = -1;
438        let mut subs = vec![];
439        subs.append(&mut self._subs);
440        subs
441    }
442    pub fn stop_proxy(&mut self, subs: Vec<Sub>) {
443        self._subs = subs;
444        self._learning = false;
445    }
446    pub fn get_subs(&self) -> Vec<String> {
447        let mut v = Vec::with_capacity(self._subs.len());
448        for sub in &self._subs {
449            v.push(format!("{} {}", sub.0, sub.1));
450        }
451        v
452    }
453}
454
455#[derive(Debug, Clone)]
456pub struct Comp {
457    pub children: Vec<Rsx>,
458}
459
460#[derive(Debug, Clone)]
461pub struct Elem {
462    pub name: &'static str,
463    pub attrs: Vec<Attribute>,
464    pub children: Vec<Rsx>,
465    pub el: Option<Element>,
466}
467
468#[derive(Debug, Clone)]
469pub struct Attribute {
470    pub key: String,
471    pub value: String,
472}
473
474#[macro_export]
475macro_rules! attributes {
476    ($(($k:expr, $v:expr)),* $(,)?) => {
477        vec![$(Attribute {key: $k, value: $v},)*]
478    }
479}
480
481impl Elem {
482    fn node(&self) -> Node {
483        self.el.clone().expect("expected element").dyn_into::<Node>().unwrap()
484    }
485    fn to_node(&mut self, document: &Document) -> Node {
486        let el = document.create_element(self.name).unwrap();
487        for attr in &self.attrs {
488            el.set_attribute(&attr.key, &attr.value).unwrap();
489            if attr.key.starts_with("on:") {
490                CALLBACKS.with(|c| {
491                    let c = c.borrow();
492                    let (v, ids) = attr.value.split_once('[').unwrap();
493                    let (ids, _) = ids.rsplit_once(']').unwrap();
494                    let cb = c.get(v).unwrap();
495                    RID.with(|r| {
496                        let mut r = r.borrow_mut();
497                        let rs = r.to_string();
498                        el.set_attribute("rid", &rs).unwrap();
499                        RECALLS.with(|rc| {
500                            rc.borrow_mut().insert(rs, RecallData {call: cb.call, ids: ids.to_string()});
501                        });
502                        *r += 1;
503                    });
504                });
505            }
506        }
507        for child in &mut self.children {
508            child.attach_to_element(&el, document);
509        }
510        self.el = Some(el.clone());
511        el.dyn_into::<Node>().unwrap()
512    }
513    fn diff(&mut self, node: &mut Node) {
514        let mut name = node.node_name();
515        if name == "#text" && node.node_value().unwrap() == "" {
516            *node = node.next_sibling().unwrap();
517            name = node.node_name();
518        }
519        if self.name == name {
520            let el = node.dyn_ref::<Element>().unwrap();
521            let attributes = el.attributes();
522            let l = self.attrs.len() as u32;
523            let mut same = true;
524            if l == attributes.length() {
525                for attr in &self.attrs {
526                    if let Some(attribute) = attributes.get_named_item(&attr.key) {
527                        let val = attribute.value();
528                        if val != attr.value {
529                            same = false;
530                            break;
531                        }
532                    } else {
533                        same = false;
534                        break;
535                    }
536                }
537            } else if l + 1 == attributes.length() {
538                if attributes.get_named_item("rid").is_some() {
539                    for attr in &self.attrs {
540                        if let Some(attribute) = attributes.get_named_item(&attr.key) {
541                            if attribute.value() != attr.value {
542                                same = false;
543                                break;
544                            }
545                        } else {
546                            same = false;
547                            break;
548                        }
549                    }
550                } else {
551                    same = false;
552                }
553            } else {
554                same = false;
555            }
556            if same {
557                return;
558            }
559        }
560        let parent = node.parent_node().unwrap();
561        DOCUMENT.with(|document| {
562            let new = self.to_node(&document);
563
564            parent.insert_before(&new, Some(&node)).unwrap();
565            *node = new;
566        });
567    }
568    fn vcheck(&mut self, old: &Rsx) -> bool {
569        if let Rsx::Element(el) = old {
570            if self.name == el.name {
571                self.el = el.el.clone();
572                Self::echeck(&el.el.as_ref().unwrap(), &self.attrs, &el.attrs);
573                return true;
574            }
575        }
576        false
577    }
578    fn echeck(node: &Element, attrs: &[Attribute], attrs2: &[Attribute]) {
579        let mut attrs = attrs.iter();
580        let mut attrs2 = attrs2.iter();
581        while let Some(attr) = attrs.next() {
582            if let Some(attr2) = attrs2.next() {
583                if attr.key == attr2.key {
584                    if attr.value == attr2.value {
585                        continue;
586                    }
587                } else {
588                    node.remove_attribute(&attr.key).unwrap();
589                }
590                if !check_recall(node, attr) {
591                    node.set_attribute(&attr.key, &attr.value).unwrap();
592                }
593            } else {
594                while let Some(attr) = attrs.next() {
595                    node.set_attribute(&attr.key, &attr.value).unwrap();
596                }
597                return;
598            }
599        }
600        if let Some(attr2) = attrs2.next() {
601            node.remove_attribute(&attr2.key).unwrap();
602            while let Some(attr) = attrs.next() {
603                node.remove_attribute(&attr.key).unwrap();
604            }
605        }
606    }
607    fn kdiff(&mut self, old: &Elem) {
608        self.el = old.el.clone();
609        Self::echeck(old.el.as_ref().unwrap(), &self.attrs[1..], &old.attrs[1..]);
610        vcheck_both(&mut self.children, &old.children);
611    }
612    fn vdiff(&mut self, old: &Rsx) {
613        if self.vcheck(old) {
614            return;
615        }
616        let parent = old.node().parent_node().unwrap();
617        DOCUMENT.with(|document| {
618            let new = self.to_node(&document);
619
620            parent.replace_child(&new, &old.node()).unwrap();
621        });
622    }
623    fn vlast(&mut self, old: &Rsx) {
624        if self.vcheck(old) {
625            return;
626        }
627        let parent = old.node().parent_node().unwrap();
628        DOCUMENT.with(|document| {
629            let new = self.to_node(&document);
630
631            parent.replace_child(&new, &old.node()).unwrap();
632        });
633    }
634}
635
636fn check_recall(node: &Element, attr: &Attribute) -> bool {
637    let mut b = false;
638    if attr.key.starts_with("on:") {
639        CALLBACKS.with(|c| {
640            let c = c.borrow();
641            let (v, ids) = attr.value.split_once('[').unwrap();
642            let (ids, _) = ids.rsplit_once(']').unwrap();
643            let cb = c.get(v).unwrap();
644            RID.with(|r| {
645                let mut r = r.borrow_mut();
646                let rs = r.to_string();
647                node.set_attribute("rid", &rs).unwrap();
648                RECALLS.with(|rc| {
649                    rc.borrow_mut().insert(rs, RecallData {call: cb.call, ids: ids.to_string()});
650                });
651                *r += 1;
652                b = true;
653            });
654        });
655    }
656    b
657}
658
659#[macro_export]
660macro_rules! element {
661    ($n:literal, $a:expr, $c: expr) => {
662        Rsx::Element(Elem {name: $n, attrs: $a, children: $c, el: None})
663    }
664}
665
666#[derive(Debug, Clone)]
667pub struct Txt {
668    text: String,
669    node: Option<Text>,
670}
671
672impl Txt {
673    fn to_node(&mut self, document: &Document) -> Node {
674        let text_node = document.create_text_node(&self.text);
675        self.node = Some(text_node.clone());
676        text_node.dyn_into::<Node>().unwrap()
677    }
678}
679
680#[derive(Debug, Clone)]
681pub struct Keys {
682    parent: Option<Node>,
683    children: Vec<Rsx>,
684}
685
686impl Keys {
687    fn kcheck(&mut self, k: &Self) {
688        self.parent = k.parent.clone();
689        let parent = self.parent.clone().expect("expected parent");
690        let mut children = self.children.iter_mut().map(|c| if let Rsx::Element(e) = c {e} else {unimplemented!()});
691        let mut children2 = k.children.iter().map(|c| if let Rsx::Element(e) = c {e} else {unimplemented!()});
692        let mut c1 = if let Some(c) = children.next() {
693            c
694        } else {
695            while let Some(child) = children2.next() {
696                parent.remove_child(&child.node()).unwrap();
697            }
698            return;
699        };
700        DOCUMENT.with(|doc| {
701            let mut c2 = if let Some(c) = children2.next() {
702                c
703            } else {
704                parent.append_child(&c1.to_node(&doc)).unwrap();
705                while let Some(child) = children.next() {
706                    parent.append_child(&child.to_node(&doc)).unwrap();
707                }
708                return;
709            };
710            let mut old: HashMap<String, (&Elem, u32)> = HashMap::new();
711
712            loop {
713                let k2 = &c2.attrs[0].value;
714                if c1.attrs[0].value == c2.attrs[0].value {
715                    c1.kdiff(c2);
716                    if let Some(c) = children.next() {
717                        c1 = c;
718                        if let Some(c) = children2.next() {
719                            c2 = c;
720                            continue;
721                        } else {
722                            parent.append_child(&c1.to_node(&doc)).unwrap();
723                            while let Some(child) = children.next() {
724                                parent.append_child(&child.to_node(&doc)).unwrap();
725                            }
726                            return;
727                        }
728                    } else {
729                        while let Some(child) = children2.next() {
730                            parent.remove_child(&child.node()).unwrap();
731                        }
732                        for (c, _) in old.values() {
733                            parent.remove_child(&c.node()).unwrap();
734                        }
735                        return;
736                    }
737                } else {
738                    let b;
739                    if let Some((child, n)) = old.remove(k2) {
740                        c1.kdiff(child);
741                        let node = parent.child_nodes().get(n).unwrap();
742                        parent.insert_before(&c1.node(), Some(&node)).unwrap();
743                    } else {
744                        let mut n = 0;
745                        for c in k.children.iter().map(|c| c.as_elem()) {
746                            let k = &c.attrs[0].value;
747                            if &c1.attrs[0].value == k {
748                                c1.kdiff(c);
749                                old.insert(c1.attrs[0].value.to_string(), (c2, n));
750                                let child = c.node();
751                                let other = c2.node();
752                                parent.replace_child(&child, &other).unwrap();
753                                break;
754                            }
755                            n += 1;
756                        }
757                        if n == k.children.len() as u32 {
758                            parent.replace_child(&c1.to_node(doc), &c2.node()).unwrap();
759                        }
760                    }
761                    if let Some(c) = children.next() {
762                        c1 = c;
763                        if let Some(c) = children2.next() {
764                            c2 = c;
765                            b = true;
766                        } else {
767                            parent.append_child(&c1.to_node(&doc)).unwrap();
768                            while let Some(child) = children.next() {
769                                parent.append_child(&child.to_node(&doc)).unwrap();
770                            }
771                            return;
772                        }
773                    } else {
774                        while let Some(child) = children2.next() {
775                            if !old.contains_key(&child.attrs[0].value) {
776                                parent.remove_child(&child.node()).unwrap();
777                            }
778                        }
779                        return;
780                    }
781                    if b {
782                        continue;
783                    }
784                    parent.insert_before(&c1.to_node(&doc), Some(&c2.node())).unwrap();
785                    if let Some(c) = children.next() {
786                        c1 = c;
787                        continue;
788                    }
789                    while let Some(child) = children2.next() {
790                        parent.remove_child(&child.node()).unwrap();
791                    }
792                    
793                }
794            }
795        });
796    }
797}
798
799#[derive(Debug, Clone)]
800pub enum Rsx {
801    Component(Comp),
802    Element(Elem),
803    Text(Txt),
804    Keyed(Keys),
805}
806
807impl Rsx {
808    pub fn component() -> Self {
809        Rsx::Component(Comp {children: vec![]})
810    }
811    pub fn as_elem(&self) -> &Elem {
812        if let Rsx::Element(e) = self {
813            e
814        } else {
815            unimplemented!();
816        }
817    }
818    pub fn new_text(text: String) -> Self {
819        Rsx::Text(Txt {text, node: None})
820    }
821    pub fn new_keyed(children: Vec<Rsx>) -> Self {
822        Rsx::Keyed(Keys {parent: None, children})
823    }
824    fn attach_to_element(&mut self, el: &Element, document: &Document) {
825        match self {
826            Self::Element(elem) => {
827                el.append_child(&elem.to_node(document)).unwrap();
828            }
829            Self::Text(text) => {
830                el.append_child(&text.to_node(document)).unwrap();
831            }
832            Self::Component(_) => unimplemented!(),
833            Self::Keyed(keyed) => {
834                for child in &mut keyed.children {
835                    el.append_child(&child.to_node(document)).unwrap();
836                }
837            }
838        }
839    }
840    fn edit(&mut self, node: &Node) {
841        DOCUMENT.with(|document| {
842            match self {
843                Self::Element(elem) => {
844                    let new = elem.to_node(&document);
845                    add_sibling(node, &new);
846                }
847                Self::Text(text) => {
848                    let new = text.to_node(&document);
849                    add_sibling(node, &new);
850                }
851                Self::Component(_) => unimplemented!(),
852                Self::Keyed(_) => unimplemented!(),
853            }
854        });
855    }
856    fn parent_node(&self) -> Option<Node> {
857        match self {
858            Self::Element(elem) => {
859                elem.el.as_ref().expect("expected element").parent_node()
860            }
861            Self::Text(text) => {
862                if let Some(node) = text.node.clone() {
863                    node.parent_node()
864                } else {
865                    panic!("expected node for text: {}", text.text)
866                }
867            }
868            Self::Component(_) => unimplemented!(),
869            Self::Keyed(_) => unimplemented!(),
870        }
871    }
872    fn node(&self) -> Node {
873        match self {
874            Self::Element(elem) => {
875                elem.node()
876            }
877            Self::Text(text) => {
878                text.node.clone().expect("expected text node").dyn_into::<Node>().expect("expected node")
879            }
880            Self::Component(_) => unimplemented!(),
881            Self::Keyed(_) => unimplemented!(),
882        }
883    }
884    fn to_node(&mut self, document: &Document) -> Node {
885        match self {
886            Self::Element(elem) => {
887                elem.to_node(document)
888            }
889            Self::Text(text) => {
890                text.to_node(document)
891            }
892            Self::Component(_) => unimplemented!(),
893            Self::Keyed(_) => unimplemented!(),
894        }
895    }
896    fn children(&self) -> Option<&Vec<Self>> {
897        match self {
898            Self::Element(elem) => {
899                if !elem.children.is_empty() {
900                    Some(&elem.children)
901                } else {
902                    None
903                }
904            }
905            Self::Text(_) => {
906                unimplemented!();
907            }
908            Self::Component(comp) => {
909                Some(&comp.children)
910            }
911            Self::Keyed(keyed) => {
912                Some(&keyed.children)
913            }
914        }
915    }
916}
917
918#[derive(Serialize, Deserialize, Debug)]
919pub enum Ctx {
920    R(String),
921}
922
923pub type Sub = (u32, i64);
924
925pub struct AppState {
926    objs: Vec<Obj>,
927    subs: Vec<Vec<Sub>>,
928}
929
930impl AppState {
931    pub fn objs(&self) -> &Vec<Obj> {
932        &self.objs
933    }
934    pub fn objs_mut(&mut self) -> &mut Vec<Obj> {
935        &mut self.objs
936    }
937    pub fn subs(&self) -> &Vec<Vec<Sub>> {
938        &self.subs
939    }
940    pub fn subs_mut(&mut self) -> &mut Vec<Vec<Sub>> {
941        &mut self.subs
942    }
943}
944
945#[derive(Clone)]
946pub enum Obj {
947    Rs(Rc<RefCell<dyn Any>>),
948    Js(Value),
949}
950
951pub fn html_escape(s: &str) -> String {
952    let mut escaped = String::new();
953    for c in s.chars() {
954        let html = match c {
955            '<' => "&lt;",
956            '>' => "&gt;",
957            '\'' => "&#x27;",
958            '"' => "&quot;",
959            '&' => "&amp;",
960            _ => {
961                escaped.push(c);
962                continue;
963            }
964        };
965        escaped.push_str(html);
966    }
967    escaped
968}
969
970pub struct RecallData {
971    pub call: fn(),
972    pub ids: String,
973}
974
975pub struct CallbackData {
976    pub new: fn(String),
977    pub call: fn(),
978}
979
980#[macro_export]
981macro_rules! log {
982    ($f:literal $($t:tt)*) => {
983        web_sys::console::log_1(&format!($f $($t)*).into());
984    };
985    ($($t:tt)*) => {
986        web_sys::console::log_1(&$($t)*);
987    };
988}
989
990fn add_sibling(node: &Node, new: &Node) {
991    match node.node_type() {
992        Node::ELEMENT_NODE => node.dyn_ref::<Element>().unwrap().after_with_node_1(new).unwrap(),
993        Node::TEXT_NODE => node.dyn_ref::<Text>().unwrap().after_with_node_1(new).unwrap(),
994        _ => unimplemented!(),
995    }
996}
997
998pub fn get_state(document: &Document, ctx_map: &mut HashMap<String, Ctx>) -> Option<AppState> {
999    let script = document.query_selector_all("script[type='app/json']").unwrap().get(0).unwrap();
1000    let text = script.text_content().unwrap();
1001    let json: Value = serde_json::from_str(&text).unwrap();
1002    let values = json.as_object().unwrap();
1003    let ctx = values.get("ctx").unwrap();
1004    let contexts = ctx.as_object().unwrap();
1005    let mut cmap = HashMap::new();
1006    for (id, n) in contexts {
1007        let c = serde_json::from_value(n.clone()).unwrap();
1008        cmap.insert(id.to_string(), c);
1009    }
1010    let object_array = values.get("objs").unwrap();
1011    let mut objs = vec![];
1012    for object in object_array.as_array().unwrap() {
1013        objs.push(Obj::Js(object.clone()));
1014    }
1015    let sub_array = values.get("subs").unwrap();
1016    let mut subs = vec![];
1017    for arr in sub_array.as_array().unwrap() {
1018        let mut sv = vec![];
1019        for sub in arr.as_array().unwrap() {
1020            let s = sub.as_str().unwrap();
1021            let nums: Vec<&str> = s.split(' ').collect();
1022            sv.push((nums[0].parse().unwrap(), nums[1].parse().unwrap()));
1023        }
1024        subs.push(sv);
1025    }
1026    let parent = script.parent_node().unwrap();
1027    parent.remove_child(&script).unwrap();
1028    *ctx_map = cmap;
1029    Some(AppState {objs, subs})
1030}
1031
1032fn check_vnodes(nodes: &NodeList, vnode_map: &mut HashMap<String, Node>) {
1033    let mut ident;
1034    for i in 0..nodes.length() {
1035        let node = nodes.get(i).unwrap();
1036        if node.node_type() == Node::COMMENT_NODE {
1037            let comment = node.text_content().unwrap();
1038            if comment.starts_with("av ") {
1039                let attrs: Vec<&str> = comment.split(' ').collect();
1040                let mut id = false;
1041                for attr in &attrs[1..] {
1042                    let (k, v) = attr.split_once('=').unwrap();
1043                    if k == "a:id" {
1044                        ident = v.to_string();
1045                        vnode_map.insert(ident, node.clone());
1046                        id = true;
1047                        break;
1048                    }
1049                }
1050                if !id {
1051                    panic!("expected id for virtual node");
1052                }
1053            }
1054        } else {
1055            check_vnodes(&node.child_nodes(), vnode_map);
1056        }
1057    }
1058}
1059   
1060pub fn setup(callbacks: HashMap<String, CallbackData>) {
1061    std::panic::set_hook(Box::new(console_error_panic_hook::hook));
1062    CALLBACKS.with(|c| {
1063        let mut cb = c.borrow_mut();
1064        *cb = callbacks;
1065    });
1066}
1067
1068pub fn rerender(mut rsx: Rsx) {
1069    CTX.with(|contexts| {
1070        let contexts = contexts.borrow();
1071        VNODE_MAP.with(|vnode_map| {
1072            let mut vnode_map = vnode_map.borrow_mut();
1073            NODE_ID.with(|node_id| {
1074                let node_id = node_id.borrow();
1075                let vn_index = match contexts.get(&*node_id).unwrap() {
1076                    Ctx::R(s) => s,
1077                };
1078                VIRT_NODES.with(|virt_nodes| {
1079                    let mut virt_nodes = virt_nodes.borrow_mut();
1080                    if let Some(virt) = virt_nodes.remove(vn_index) {
1081                        vupdate(&mut rsx, &virt, false);
1082                    } else {
1083                        DOCUMENT.with(|document| {
1084                            let nodes = document.body().unwrap().child_nodes();
1085                            check_vnodes(&nodes, &mut vnode_map);
1086                            let mut node = vnode_map.get(vn_index).unwrap().clone().next_sibling().unwrap();
1087                            update(&mut rsx, &mut node);
1088                            close_vnode(&document, &node);
1089                        });
1090                    }
1091                    virt_nodes.insert(vn_index.to_string(), rsx);
1092                });
1093            });
1094        });
1095    });
1096}
1097
1098#[wasm_bindgen]
1099pub fn recall(rid: &str) -> bool {
1100    let mut b = false;
1101    RECALLS.with(|r| {
1102        let recalls = r.borrow();
1103        if let Some(rc) = recalls.get(rid) {
1104            let r = rc.call;
1105            IDS.with(|id| {
1106                let arr: Vec<String> = rc.ids.split(' ').map(|s| s.to_string()).collect();
1107                *id.borrow_mut() = arr;
1108            });
1109            drop(recalls);
1110            (r)();
1111            b = true;
1112        }
1113    });
1114    b
1115}
1116
1117fn check_mount(node_id: &str) -> bool {
1118    let mut b = true;
1119    CTX.with(|contexts| {
1120        let contexts = contexts.borrow();
1121        MOUNTED.with(|m| {
1122            let mounted = m.borrow();
1123            if let Some(vn_index) = contexts.get(node_id) {
1124                let index = match vn_index {
1125                    Ctx::R(s) => s,
1126                };
1127                if mounted.contains(index) {
1128                    b = false;
1129                }
1130            }
1131        });
1132    });
1133    b
1134}
1135
1136#[wasm_bindgen]
1137pub fn call(callback: &str, node_id: &str) -> Result<(), JsValue> {
1138    let (name, arr) = callback.split_once('[').unwrap();
1139    let (arr, _) = arr.rsplit_once(']').unwrap();
1140    let arr: Vec<String> = arr.split(' ').map(|s| s.to_string()).collect();
1141
1142    CALLBACKS.with(|c| {
1143        let cbc = {
1144            let mut callbacks = c.borrow_mut();
1145            if let Some(cb) = callbacks.get_mut(name) {
1146                NODE_ID.with(|n| *n.borrow_mut() = node_id.to_string());
1147                IDS.with(|id| {
1148                    *id.borrow_mut() = arr;
1149                });
1150
1151                if check_mount(node_id) {
1152                    (cb.new)(node_id.to_string());
1153                    CTX.with(|contexts| {
1154                        let contexts = contexts.borrow();
1155                        MOUNTED.with(|m| {
1156                            let mut mounted = m.borrow_mut();
1157                            if let Some(vn_index) = contexts.get(node_id) {
1158                                let index = match vn_index {
1159                                    Ctx::R(s) => s,
1160                                };
1161                                mounted.insert(index.to_string());
1162                            }
1163                        });
1164                    });
1165                }
1166                cb.call
1167            } else {
1168                panic!("expected callback");
1169            }
1170        };
1171        cbc();
1172    });
1173
1174    Ok(())
1175}
1176
1177#[derive(Debug)]
1178pub struct ScopeVar {
1179    pub rf: Rc<RefCell<dyn Any>>,
1180    pub index: Option<usize>,
1181}
1182
1183impl ScopeVar {
1184    fn new(rf: Rc<RefCell<dyn Any>>, index: Option<usize>) -> Self {
1185        Self {rf, index}
1186    }
1187}
1188
1189pub fn lexical_scope() -> Vec<ScopeVar> {
1190    let mut v = vec![];
1191    APP_STATE.with(|app| {
1192        let app = app.borrow();
1193        IDS.with(|ids| {
1194            for id in ids.borrow().iter() {
1195                if let Some((f, s)) = id.split_once('-') {
1196                    let f: usize = f.parse().expect("problem parsing id for lexical scope");
1197                    let s: usize = s.parse().expect("problem parsing index for lexical scope");
1198                    if let Obj::Rs(var) = &app.as_ref().expect("could not get app state").objs[f] {
1199                        v.push(ScopeVar::new(var.clone(), Some(s)));
1200                    } else {
1201                        panic!("expected Rust type to be restored");
1202                    }
1203                } else {
1204                    let id: usize = id.parse().expect("problem parsing id for lexical scope");
1205                    if let Obj::Rs(var) = &app.as_ref().expect("could not get app state").objs[id] {
1206                        v.push(ScopeVar::new(var.clone(), None));
1207                    } else {
1208                        panic!("expected Rust type to be restored");
1209                    }
1210                }
1211            }
1212        })
1213    });
1214    v
1215}
1216
1217fn add_children(children: &mut Vec<Rsx>, node: &Node) {
1218    DOCUMENT.with(|document| {
1219        for child in children {
1220            node.append_child(&child.to_node(document)).expect("problem appending child");
1221        }
1222    });
1223}
1224
1225fn update(rsx: &mut Rsx, node: &mut Node) {
1226    match rsx {
1227        Rsx::Element(element) => {
1228            element.diff(node);
1229            if let Some(mut first_child) = node.first_child() {
1230                check_siblings(&mut element.children, &mut first_child);
1231            } else if !element.children.is_empty() {
1232                add_children(&mut element.children, node);
1233            }
1234        }
1235        Rsx::Text(text) => {
1236            set_content(node, text);
1237        }
1238        Rsx::Component(comp) => {
1239            check_siblings(&mut comp.children, node);
1240        }
1241        Rsx::Keyed(key) => {
1242            key.parent = node.parent_node();
1243            check_siblings(&mut key.children, node);
1244        }
1245    }
1246}
1247
1248fn vupdate(rsx: &mut Rsx, node: &Rsx, last: bool) {
1249    match rsx {
1250        Rsx::Element(element) => {
1251            if !last {
1252                element.vdiff(node);
1253            } else {
1254                element.vlast(node);
1255            }
1256            vcheck_children(&mut element.children, node);
1257        }
1258        Rsx::Text(text) => {
1259            if let Rsx::Text(t) = node {
1260                text.node = t.node.clone();
1261                if text.text == t.text {
1262                    return;
1263                } else {
1264                    text.node.as_ref().unwrap().set_data(&text.text);
1265                }
1266            }
1267            vset_content(node, text);
1268        }
1269        Rsx::Component(comp) => {
1270            vcheck_children(&mut comp.children, node);
1271        }
1272        Rsx::Keyed(keyed) => {
1273            if let Rsx::Keyed(k) = node {
1274                keyed.kcheck(k);
1275            } else {
1276                unimplemented!();
1277            }
1278        }
1279    }
1280}
1281
1282fn avcheck(node: &Node) -> bool {
1283    node.node_type() == Node::COMMENT_NODE && node.text_content().unwrap() == "/av"
1284}
1285
1286fn check_siblings(children: &mut Vec<Rsx>, node: &mut Node) {
1287    let mut children = children.iter_mut();
1288    let l = children.len();
1289    let mut n = 0;
1290
1291    loop {
1292        if let Some(mut child) = children.next() {
1293            update(&mut child, node);
1294            
1295            if let Some(sib) = node.next_sibling() {
1296                if avcheck(&sib) {
1297                    while let Some(c) = children.next() {
1298                        c.edit(&node);
1299                        *node = node.next_sibling().unwrap();
1300                    }
1301                    return;
1302                }
1303
1304                if n < l - 1 {
1305                    *node = sib;
1306                }
1307            } else {
1308                if n < l - 1 {
1309                    child.edit(&node);
1310                    while let Some(c) = children.next() {
1311                        if let Some(sib) = node.next_sibling() {
1312                            *node = sib;
1313                            c.edit(&node);
1314                        } else {
1315                            c.edit(&node);
1316                            while let Some(d) = children.next() {
1317                                d.edit(&node);
1318                            }
1319                            return;
1320                        }
1321                    }
1322                }
1323                return;
1324            };
1325        } else {
1326            if let Some(s) = node.next_sibling() {
1327                let parent = node.parent_node().unwrap();
1328                RECALLS.with(|r| {
1329                    let mut recall = r.borrow_mut();
1330                    remove_recall(&mut recall, &parent, &s);
1331                    while let Some(sib) = node.next_sibling() {
1332                        if !avcheck(&sib) {
1333                            remove_recall(&mut recall, &parent, &sib);
1334                        } else {
1335                            return;
1336                        }
1337                    }
1338                });
1339            }
1340            return;
1341        }
1342        n += 1;
1343    }
1344}
1345
1346fn vcheck_children(children: &mut Vec<Rsx>, node: &Rsx) {
1347    if let Some(node) = node.children() {
1348        vcheck_both(children, node);
1349    } else {
1350        if !children.is_empty() {
1351            add_children(children, &node.node());
1352        }
1353        return;
1354    }
1355}
1356
1357fn vcheck_both(children: &mut Vec<Rsx>, node: &Vec<Rsx>) {
1358    let m = node.len();
1359    let mut node_children = node.iter();
1360    let mut children = children.iter_mut();
1361    let mut n = 0;
1362    let mut node = node_children.next().unwrap();
1363
1364    loop {
1365        if let Some(mut child) = children.next() {
1366            let last = children.len() == 0;
1367            vupdate(&mut child, &node, last);
1368
1369            if n + 1 == m {
1370                if children.len() > 0 {
1371                    let mut sib = node.node();
1372                    while let Some(c) = children.next() {
1373                        let next_sibling = {
1374                            c.edit(&sib);
1375                            sib.next_sibling().unwrap()
1376                        };
1377                        sib = next_sibling;
1378                    }
1379                }
1380                return;
1381            } 
1382        } else {
1383            let parent = node.parent_node().unwrap();
1384            RECALLS.with(|r| {
1385                let mut recall = r.borrow_mut();
1386                remove_recall(&mut recall, &parent, &node.node());
1387                while let Some(sib) = node_children.next() {
1388                    remove_recall(&mut recall, &parent, &sib.node());
1389                }
1390            });
1391            return;
1392        }
1393        if let Some(n) = node_children.next() {
1394            node = n;
1395        } else {
1396            break;
1397        }
1398        n += 1;
1399    }
1400}
1401
1402fn remove_recall(recalls: &mut HashMap<String, RecallData>, parent: &Node, child: &Node) {
1403    if child.node_type() == Node::ELEMENT_NODE {
1404        let el = child.dyn_ref::<Element>().unwrap();
1405        let attrs = el.attributes();
1406        if let Some(rid) = attrs.get_named_item("rid") {
1407            recalls.remove(&rid.value());
1408        }
1409    }
1410    parent.remove_child(child).unwrap();
1411}
1412
1413fn replace_recall(recalls: &mut HashMap<String, RecallData>, parent: &Node, child: &Node, new: &Node) {
1414    if child.node_type() == Node::ELEMENT_NODE {
1415        let el = child.dyn_ref::<Element>().unwrap();
1416        let attrs = el.attributes();
1417        if let Some(rid) = attrs.get_named_item("rid") {
1418            recalls.remove(&rid.value());
1419        }
1420    }
1421    parent.replace_child(new, child).unwrap();
1422}
1423
1424fn set_content(node: &mut Node, content: &mut Txt) {
1425    let text = Text::new_with_data(&content.text).unwrap();
1426    let parent = node.parent_node().unwrap();
1427    RECALLS.with(|r| {
1428        let mut recall = r.borrow_mut();
1429        content.node = Some(text.clone());
1430        let text_node = text.dyn_into::<Node>().unwrap();
1431        replace_recall(&mut recall, &parent, node, &text_node);
1432        *node = text_node;
1433    });
1434}
1435
1436fn vset_content(node: &Rsx, content: &mut Txt) {
1437    let text = Text::new_with_data(&content.text).unwrap();
1438    let parent = node.parent_node().unwrap();
1439    RECALLS.with(|r| {
1440        let mut recall = r.borrow_mut();
1441        content.node = Some(text.clone());
1442        let text_node = text.dyn_into::<Node>().unwrap();
1443        replace_recall(&mut recall, &parent, &node.node(), &text_node);
1444    });
1445}
1446
1447fn close_vnode(document: &Document, node: &Node) {
1448    if let Some(n) = node.next_sibling() {
1449        if n.node_type() == Node::COMMENT_NODE && n.text_content().unwrap() != "/av" {
1450            let c = document.create_comment("/av").dyn_into::<Node>().unwrap();
1451            add_sibling(&n, &c);
1452        }
1453    }
1454}