polish: clean up to web

This commit is contained in:
Jonathan Kelley committed 2021-09-24 20:47:59 -04:00
1 parent 823adc0834
commit b43a964f98
4 files changed
+55 -87

No files matched your search

+1
View File
@@ -74,6 +74,7 @@ separator = "0.4.1"
uuid = { version = "0.8.2", features = ["v4", "wasm-bindgen"] }
dioxus-hooks = { path = "../hooks" }
serde = { version = "1.0.126", features = ["derive"] }
reqwest = { version = "0.11", features = ["json"] }
# rand = { version="0.8.4", features=["small_rng"] }
# surf = { version = "2.3.1", default-features = false, features = [
+17 -40
View File
@@ -1,24 +1,13 @@
//! Basic example that renders a simple VNode to the browser.
use dioxus::events::on::MouseEvent;
use dioxus_core as dioxus;
use dioxus_core::prelude::*;
use dioxus_hooks::*;
use dioxus_html as dioxus_elements;
// use wasm_timer;
use std::future::Future;
use std::{pin::Pin, time::Duration};
use dioxus::prelude::*;
fn main() {
// Setup logging
console_error_panic_hook::set_once();
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
dioxus_web::launch(App, |c| c)
dioxus_web::launch(APP, |c| c)
}
#[derive(serde::Deserialize)]
@@ -26,14 +15,13 @@ struct DogApi {
message: String,
}
const ENDPOINT: &str = "https://dog.ceo/api/breeds/image/random/";
static App: FC<()> = |cx, props|{
static APP: FC<()> = |cx, _props| {
let state = use_state(cx, || 0);
let dog_node = use_suspense(
const ENDPOINT: &str = "https://dog.ceo/api/breeds/image/random/";
let doggo = use_suspense(
cx,
|| surf::get(ENDPOINT).recv_json::<DogApi>(),
|| async { reqwest::get(ENDPOINT).await.unwrap().json::<DogApi>().await },
|cx, res| match res {
Ok(res) => rsx!(
cx,
@@ -45,29 +33,18 @@ static App: FC<()> = |cx, props|{
},
);
cx.render(rsx! {
div { style: { align_items: "center" }
section { class: "py-12 px-4 text-center"
div { class: "w-full max-w-2xl mx-auto"
span { class: "text-sm font-semibold"
"count: {state}"
}
br {}
div {
button {
onclick: move |_| state.set(state + 1)
"incr"
}
br {}
button {
onclick: move |_| state.set(state - 1)
"decr"
}
}
div {
h1{"doggo!"}
{dog_node}
}
rsx!(cx, div { align_items: "center"
section { class: "py-12 px-4 text-center"
div { class: "w-full max-w-2xl mx-auto"
span { class: "text-sm font-semibold"
"count: {state}"
}
div {
button { onclick: move |_| state.set(state + 1), "incr" }
button { onclick: move |_| state.set(state - 1), "decr" }
}
div {
{doggo}
}
}
}
+6 -21
View File
@@ -1,18 +1,9 @@
//! Basic example that renders a simple VNode to the browser.
// all these imports are done automatically with the `dioxus` crate and `prelude`
// need to do them manually for this example
use dioxus::events::on::MouseEvent;
use dioxus_core as dioxus;
use dioxus_core::prelude::*;
use dioxus_hooks::*;
use dioxus_html as dioxus_elements;
use dioxus::prelude::*;
use dioxus_web::*;
use std::future::Future;
use std::{pin::Pin, time::Duration};
fn main() {
// Setup logging
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
@@ -22,12 +13,10 @@ fn main() {
dioxus_web::launch(APP, |c| c)
}
static APP: FC<()> = |cx, props| {
static APP: FC<()> = |cx, _| {
let mut count = use_state(cx, || 3);
let mut content = use_state(cx, || String::from("h1"));
let mut text_content = use_state(cx, || String::from("Hello, world!"));
log::debug!("running scope...");
let content = use_state(cx, || String::from("h1"));
let text_content = use_state(cx, || String::from("Hello, world!"));
cx.render(rsx! {
div {
@@ -39,8 +28,7 @@ static APP: FC<()> = |cx, props| {
oninput: move |e| text_content.set(e.value())
}
br {}
{(0..10).map(|f| {
{(0..10).map(|_| {
rsx!(
button {
onclick: move |_| count += 1,
@@ -74,7 +62,7 @@ static APP: FC<()> = |cx, props| {
{render_bullets(cx)}
Child {}
CHILD {}
}
})
};
@@ -97,7 +85,4 @@ fn render_list(cx: Context, count: usize) -> DomTree {
rsx!(cx, ul { {items} })
}
static Child: FC<()> = |cx, props| {
// render
rsx!(cx, div {"hello child"})
};
static CHILD: FC<()> = |cx, _| rsx!(cx, div {"hello child"});
+31 -26
View File
@@ -1,3 +1,12 @@
//! Implementation of a renderer for Dioxus on the web.
//!
//! Oustanding todos:
//! - Removing event listeners (delegation)
//! - Passive event listeners
//! - no-op event listener patch for safari
//! - tests to ensure dyn_into works for various event types.
//! - Partial delegation?>
use dioxus_core::{
events::{SyntheticEvent, UserEvent},
mutations::NodeRefMutation,
@@ -29,7 +38,7 @@ pub struct WebsysDom {
// map of listener types to number of those listeners
// This is roughly a delegater
// TODO: check how infero delegates its events - some are more performant
listeners: FxHashMap<&'static str, (usize, Closure<dyn FnMut(&Event)>)>,
listeners: FxHashMap<&'static str, ListenerEntry>,
// We need to make sure to add comments between text nodes
// We ensure that the text siblings are patched by preventing the browser from merging
@@ -38,6 +47,9 @@ pub struct WebsysDom {
// -> https://github.com/facebook/react/pull/5753
last_node_was_text: bool,
}
type ListenerEntry = (usize, Closure<dyn FnMut(&Event)>);
impl WebsysDom {
pub fn new(root: Element, cfg: WebConfig, sender_callback: Rc<dyn Fn(SchedulerMsg)>) -> Self {
let document = load_document();
@@ -92,7 +104,6 @@ impl WebsysDom {
pub fn process_edits(&mut self, edits: &mut Vec<DomEdit>) {
for edit in edits.drain(..) {
// log::info!("Handling edit: {:#?}", edit);
match edit {
DomEdit::PushRoot { id: root } => self.push(root),
DomEdit::PopRoot => self.pop(),
@@ -423,34 +434,29 @@ impl WebsysDom {
}
#[derive(Debug, Default)]
pub struct Stack {
pub list: Vec<Node>,
struct Stack {
list: Vec<Node>,
}
impl Stack {
#[inline]
pub fn with_capacity(cap: usize) -> Self {
fn with_capacity(cap: usize) -> Self {
Stack {
list: Vec::with_capacity(cap),
}
}
#[inline]
pub fn push(&mut self, node: Node) {
fn push(&mut self, node: Node) {
self.list.push(node);
}
#[inline]
pub fn pop(&mut self) -> Node {
fn pop(&mut self) -> Node {
self.list.pop().unwrap()
}
#[inline]
pub fn clear(&mut self) {
self.list.clear();
}
pub fn top(&self) -> &Node {
fn top(&self) -> &Node {
match self.list.last() {
Some(a) => a,
None => panic!("Called 'top' of an empty stack, make sure to push the root first"),
@@ -458,6 +464,8 @@ impl Stack {
}
}
// todo: some of these events are being casted to the wrong event type.
// We need tests that simulate clicks/etc and make sure every event type works.
fn virtual_event_from_websys_event(event: web_sys::Event) -> SyntheticEvent {
use crate::events::*;
use dioxus_core::events::on::*;
@@ -549,12 +557,13 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
let typ = event.type_();
log::debug!("Event type is {:?}", typ);
let attrs = target.attributes();
for x in 0..attrs.length() {
let attr: Attr = attrs.item(x).unwrap();
// log::debug!("attrs include: {:#?}, {:#?}", attr.name(), attr.value());
// TODO: clean this up
if cfg!(debug_assertions) {
let attrs = target.attributes();
for x in 0..attrs.length() {
let attr: Attr = attrs.item(x).unwrap();
// log::debug!("attrs include: {:#?}, {:#?}", attr.name(), attr.value());
}
}
use anyhow::Context;
@@ -576,12 +585,8 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
.and_then(|raw_id| raw_id.parse::<u64>().ok())
.context("failed to parse real id")?;
// Call the trigger
// log::debug!("decoded scope_id: {}, node_id: {:#?}", gi_id, real_id);
let triggered_scope = gi_id;
// let triggered_scope: ScopeId = KeyData::from_ffi(gi_id).into();
// log::debug!("Triggered scope is {:#?}", triggered_scope);
Ok(UserEvent {
name: event_name_from_typ(&typ),
event: virtual_event_from_websys_event(event.clone()),
@@ -590,14 +595,14 @@ fn decode_trigger(event: &web_sys::Event) -> anyhow::Result<UserEvent> {
})
}
pub fn load_document() -> Document {
pub(crate) fn load_document() -> Document {
web_sys::window()
.expect("should have access to the Window")
.document()
.expect("should have access to the Document")
}
pub fn event_name_from_typ(typ: &str) -> &'static str {
fn event_name_from_typ(typ: &str) -> &'static str {
match typ {
"copy" => "copy",
"cut" => "cut",