edita 0.2.1

edita is a simple block html-based editor built with rust
Documentation
use edita_core::process_nodes;
use edita_core::Block;
use edita_core::Editor;
use hirola::dom::Html;
use hirola::dom::XEffect;
use hirola::prelude::*;
use hirola::signal::LocalBoxSignal;
use hirola::signal::SignalExt;
use serde::Serialize;
use wasm_bindgen::JsCast;
use web_sys::HtmlElement;

use crate::nodes::EditorNode;
use crate::state::EditorState;

pub struct HtmlBlock;

#[derive(Clone, Serialize, Debug)]
pub struct HtmlNode(String);

impl crate::nodes::Node for HtmlNode {
    fn render(&self) -> hirola::dom::Dom {
        html! { <div data-node-atom="true" contenteditable="false" x:html=self.0.as_str()></div> }
    }
}

impl Block for HtmlBlock {
    type Node = EditorNode;
    type Input = web_sys::Node;
    type State = EditorState;
    fn accepts(&self, _node: &web_sys::Node) -> bool {
        true
    }

    fn parse(
        &self,
        _editor: &Editor<Self::Node, EditorState, web_sys::Node>,
        node: &web_sys::Node,
    ) -> EditorNode {
        let element: &HtmlElement = node.dyn_ref().unwrap();
        EditorNode::Html(HtmlNode(element.outer_html()))
    }
}

pub trait EditorExt {
    fn export(&self) -> Vec<EditorNode>;
    fn signal(&self) -> LocalBoxSignal<Vec<EditorNode>>;
}

impl EditorExt for Editor<EditorNode, EditorState, web_sys::Node> {
    fn export(&self) -> Vec<EditorNode> {
        let element = self.node().get().inner_element();
        let child_nodes = element.child_nodes();
        let mut nodes = vec![];
        for i in 0..child_nodes.length() {
            nodes.push(child_nodes.get(i).unwrap());
        }
        process_nodes(self, nodes)
    }

    fn signal(&self) -> LocalBoxSignal<Vec<EditorNode>> {
        self.notify
            .signal()
            .map(move |_| self.export())
            .boxed_local()
    }
}