Skip to content

Commit

Permalink
Merge pull request #91 from ivanceras/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
ivanceras authored Apr 4, 2024
2 parents 52b586c + f5d359b commit 9ea3493
Show file tree
Hide file tree
Showing 21 changed files with 91 additions and 192 deletions.
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sauron"
version = "0.60.7"
version = "0.61.0"
authors = [ "Jovansonlee Cesar <[email protected]>" ]
license = "MIT"
description = "A versatile web framework and library for building client-side and/or server-side web applications"
Expand All @@ -14,9 +14,9 @@ edition = "2021"
maintenance = { status = "actively-developed" }

[dependencies]
sauron-core = { version = "0.60", path = "crates/core", default-features = false }
sauron-macro = { version = "0.60", path = "crates/macro", optional = true }
sauron-html-parser = { version = "0.60", path = "crates/html-parser", optional = true }
sauron-core = { version = "0.61", path = "crates/core", default-features = false }
sauron-macro = { version = "0.61", path = "crates/macro", optional = true }
sauron-html-parser = { version = "0.61", path = "crates/html-parser", optional = true }

[features]
default = ["with-dom", "with-node-macro", "custom_element", "with-interning", "with-jss"]
Expand Down
14 changes: 14 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
# Changelog

## 0.61.0
- add template system, skip_diff
- web_sys::Node is now wrapped with DomNode, the event listeners
is now managed from its containing DomNode, instead of from the Program.
when a DomNode is removed and goes out of scope, so does its associated event closures are dropped
- `Cmd<Msg>` can now be mapped into `Effects<Msg,..>` and vice versa
- The `mt-dom` crate is now part of `core` in the `vdom` module. This change is necessary
to improve code coherence and simplicity, lesser number of generic types has to be passed arround.
- remove `inner_html` as a function to set html via html attributes.
- This cause breakage in tracking the DOMTree as new nodes could be inserted dynamically without the runtime knowing it.
- Rename `safe_html` to `symbol` as its usage is intended for html entities such as `&nbsp;` `&quote;` etc.
- A `safe_html` function is added and use `html-parser` to parse dynamic html and convert it into a safe dom-tree.


## 0.60.7
- feat: add selectionchange event and document_event_listener

Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ impl App {
}
}

impl Application<Msg> for App {
impl Application for App {

type MSG = Msg;

fn view(&self) -> Node<Msg> {
node! {
<main>
Expand All @@ -82,7 +85,7 @@ impl Application<Msg> for App {
}
}

fn update(&mut self, msg: Msg) -> Cmd<Self, Msg> {
fn update(&mut self, msg: Msg) -> Cmd<Msg> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Expand Down Expand Up @@ -147,7 +150,7 @@ edition = "2021"
crate-type = ["cdylib"]

[dependencies]
sauron = "0.60.0"
sauron = "0.61.0"
```

#### Prerequisite:
Expand Down
13 changes: 2 additions & 11 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,7 @@
- [X] enum Command{Cmd,Sub} into one unified type.
- [X] Cmd is a vec of Command
- Sauron just consilidate them into one enum struct for simplicity
- [ ] Remove `Modifier` and `measurements`
- [ ] Have a measurement in the Application trait
- [ ] Remove StatefulComponent as it is now the same as Application and serve the same purpose
- add methods for Application:
- attribute_changed
- remove_attribute
- append_child
- remove_child
- connected_callback
- disconnected_callback
- adopted_callback
- [X] Remove `Modifier` and `measurements`

## Features
- [X] Storage service (May not be needed since the user can directly use web-sys)
Expand Down Expand Up @@ -415,6 +405,7 @@
- [X] Runtime errors when using fragments
- [X] usage of `classes_flag` seems to be broken with complext trait requirement.
- [X] This should work very simply `classes_flag([("todo", true), ("editor", is_editing)])`
- [ ] Organize the generated docs, such that the most commonly used structs and enums are displayed on the first page of docs.rs/sauron instead of under prelude module

## Limitations
- ~~In rust, no two closures, even if identical, have the same type. Therefore closure can not be check for equality.~~ Solved by using the original type_id of the function callback
Expand Down
4 changes: 2 additions & 2 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sauron-core"
version = "0.60.7"
version = "0.61.2"
authors = [ "Jovansonlee Cesar <[email protected]>" ]
license = "MIT"
description = "An html library for building client side webapps"
Expand All @@ -14,7 +14,7 @@ edition = "2021"
maintenance = { status = "actively-developed" }

[features]
default = ["with-dom", "ensure-check", "ensure-attr-set"]
default = ["with-dom", "ensure-check", "ensure-attr-set", "with-lookup"]
with-dom = ["wasm-bindgen", "js-sys", "web-sys", "wasm-bindgen-futures"] # for client-side usage
with-lookup = [] #enumerates html tags and attributes
with-measure = [] # log traces for measurements in various parts of the system where performance matters.
Expand Down
2 changes: 0 additions & 2 deletions crates/core/src/dom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
pub use component::Component;
pub use effects::Effects;
pub use modifier::Modifier;
pub use cmd::Cmd;

mod component;
mod effects;
mod modifier;
mod cmd;

use cfg_if::cfg_if;
Expand Down
9 changes: 2 additions & 7 deletions crates/core/src/dom/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,14 @@ pub trait Application: Sized + 'static {
/// This is for diagnostic and performance measurement purposes.
///
/// Warning: DO NOT use for anything else other than the intended purpose
fn measurements(&self, measurements: Measurements) -> Cmd<Self::MSG> {
log::debug!("Measurements: {:#?}", measurements);
Cmd::none().no_render()
fn measurements(&mut self, _measurements: Measurements){
}
}

/// Contains the time it took for the last app update call for the component
/// TODO: Maybe rename to Diagnostics
#[derive(Clone, Debug, PartialEq, Default)]
#[derive(Clone, Copy, Debug, PartialEq, Default)]
pub struct Measurements {
/// The application can name this measurement to determine where this measurement is coming
/// from.
pub name: String,
/// The number of DOM nodes in this Component
pub node_count: usize,
/// Time it took for the Component to build it's view
Expand Down
30 changes: 12 additions & 18 deletions crates/core/src/dom/cmd.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
use crate::dom::spawn_local;
use futures::channel::mpsc;
use futures::channel::mpsc::UnboundedReceiver;
use futures::StreamExt;
use std::future::Future;
use std::pin::Pin;
use crate::dom::Effects;
use crate::dom::Modifier;
#[cfg(feature = "with-dom")]
use wasm_bindgen::closure::Closure;

/// Cnd is a way to tell the Runtime that something needs to be executed
pub struct Cmd<MSG>{
/// commands
pub(crate) commands: Vec<Command<MSG>>,
pub(crate) modifier: Modifier,
}

/// encapsulate anything a component can do
pub enum Command<MSG> {
/// A task with one single resulting MSG
Action(Action<MSG>),
#[cfg(feature = "with-dom")]
/// A task with recurring resulting MSG
Sub(Sub<MSG>),
}
Expand All @@ -43,14 +42,12 @@ where
{
Self{
commands: vec![Command::single(f)],
modifier: Default::default(),
}
}
/// Creates a Cmd which will be polled multiple times
pub fn recurring(rx: UnboundedReceiver<MSG>, event_closure: Closure<dyn FnMut(web_sys::Event)>) -> Self {
Self{
commands: vec![Command::sub(rx, event_closure)],
modifier: Default::default(),
}
}

Expand All @@ -62,7 +59,6 @@ where
{
Cmd{
commands: self.commands.into_iter().map(|t|t.map_msg(f.clone())).collect(),
modifier: Default::default(),
}
}

Expand All @@ -73,22 +69,15 @@ where
commands.extend(task.commands);
}
Self {commands,
modifier: Default::default(),
}
}

///
pub fn none() -> Self {
Self{commands: vec![],
modifier: Default::default(),
}
}

///
pub fn no_render(mut self) -> Self {
self.modifier.should_update_view = false;
self
}

}

Expand All @@ -103,12 +92,9 @@ impl<MSG> From<Effects<MSG, ()>> for Cmd<MSG>
let Effects {
local,
external:_,
modifier,
} = effects;

let mut cmd = Cmd::batch(local.into_iter().map(Cmd::from));
cmd.modifier = modifier;
cmd
Cmd::batch(local.into_iter().map(Cmd::from))
}
}

Expand All @@ -124,7 +110,9 @@ where
{
Self::Action(Action::new(f))
}

///
#[cfg(feature = "with-dom")]
pub fn sub(rx: UnboundedReceiver<MSG>, event_closure: Closure<dyn FnMut(web_sys::Event)>) -> Self {
Self::Sub(Sub{
receiver: rx,
Expand All @@ -140,6 +128,7 @@ where
{
match self {
Self::Action(task) => Command::Action(task.map_msg(f)),
#[cfg(feature = "with-dom")]
Self::Sub(task) => Command::Sub(task.map_msg(f)),
}
}
Expand All @@ -148,6 +137,7 @@ where
pub async fn next(&mut self) -> Option<MSG> {
match self {
Self::Action(task) => task.next().await,
#[cfg(feature = "with-dom")]
Self::Sub(task) => task.next().await,
}
}
Expand Down Expand Up @@ -216,13 +206,15 @@ where
}
}

#[cfg(feature = "with-dom")]
/// Sub is a recurring operation
pub struct Sub<MSG> {
pub(crate) receiver: UnboundedReceiver<MSG>,
/// store the associated closures so it is not dropped before being event executed
pub(crate) event_closure: Closure<dyn FnMut(web_sys::Event)>,
}

#[cfg(feature = "with-dom")]
impl<MSG> Sub<MSG>
where
MSG: 'static,
Expand All @@ -242,11 +234,13 @@ where
mut receiver,
event_closure,
} = self;
spawn_local(async move {

crate::dom::spawn_local(async move {
while let Some(msg) = receiver.next().await {
tx.start_send(f(msg)).expect("must send");
}
});

Sub {
receiver: rx,
event_closure,
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/dom/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ use crate::{dom::Effects, vdom::Node};
use derive_where::derive_where;
use std::any::TypeId;

#[cfg(feature = "with-dom")]
pub use stateful_component::{stateful_component, StatefulComponent, StatefulModel};

#[cfg(feature = "custom_element")]
pub use web_component::{register_web_component, WebComponent, WebComponentWrapper};

#[cfg(feature = "with-dom")]
mod stateful_component;
#[cfg(feature = "use-template")]
pub(crate) mod template;
Expand Down
5 changes: 2 additions & 3 deletions crates/core/src/dom/component/stateful_component.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![allow(unused)]
use crate::dom::events::on_mount;
use crate::dom::program::MountProcedure;
use crate::dom::Application;
Expand All @@ -15,7 +14,6 @@ use std::any::TypeId;
use std::cell::RefCell;
use std::fmt;
use std::rc::Rc;
use wasm_bindgen::JsValue;

/// A component that can be used directly in the view without mapping
pub trait StatefulComponent {
Expand Down Expand Up @@ -174,7 +172,8 @@ where
}))
}

impl Into<DomAttrValue> for JsValue {
#[cfg(feature = "with-dom")]
impl Into<DomAttrValue> for wasm_bindgen::JsValue {
fn into(self) -> DomAttrValue {
if let Some(v) = self.as_bool() {
DomAttrValue::Simple(v.into())
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/dom/component/web_component.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::dom::program::MountProcedure;
use crate::dom::{Application, Modifier, Program};
use crate::dom::{Application, Program};
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;

Expand Down Expand Up @@ -177,7 +177,7 @@ where
.borrow_mut()
.connected_callback();
self.program
.update_dom(&Modifier::default())
.update_dom()
.expect("must update dom");
}

Expand Down
Loading

0 comments on commit 9ea3493

Please sign in to comment.