feat: complete html to rsx rosetta

This commit is contained in:
Jonathan Kelley committed 2022-12-28 16:22:20 -05:00
1 parent d22577082c
commit bc3cf6501c
8 files changed
+159 -87

No files matched your search

+41 -41
View File
@@ -18,49 +18,49 @@ members = [
"packages/tui",
"packages/native-core",
"packages/native-core-macro",
"packages/rsx-rosetta",
"docs/guide",
"packages/html-to-rsx"
]
# This is a "virtual package"
# It is not meant to be published, but is used so "cargo run --example XYZ" works properly
[package]
name = "dioxus-examples"
version = "0.0.0"
authors = ["Jonathan Kelley"]
edition = "2021"
description = "Top level crate for the Dioxus repository"
license = "MIT OR Apache-2.0"
repository = "https://github.com/DioxusLabs/dioxus/"
homepage = "https://dioxuslabs.com"
documentation = "https://dioxuslabs.com"
keywords = ["dom", "ui", "gui", "react", "wasm"]
rust-version = "1.60.0"
publish = false
# # This is a "virtual package"
# # It is not meant to be published, but is used so "cargo run --example XYZ" works properly
# [package]
# name = "dioxus-examples"
# version = "0.0.0"
# authors = ["Jonathan Kelley"]
# edition = "2021"
# description = "Top level crate for the Dioxus repository"
# license = "MIT OR Apache-2.0"
# repository = "https://github.com/DioxusLabs/dioxus/"
# homepage = "https://dioxuslabs.com"
# documentation = "https://dioxuslabs.com"
# keywords = ["dom", "ui", "gui", "react", "wasm"]
# rust-version = "1.60.0"
# publish = false
[dev-dependencies]
dioxus = { path = "./packages/dioxus" }
dioxus-desktop = { path = "./packages/desktop" }
dioxus-ssr = { path = "./packages/ssr" }
dioxus-router = { path = "./packages/router" }
fermi = { path = "./packages/fermi" }
futures-util = "0.3.21"
log = "0.4.14"
num-format = "0.4.0"
separator = "0.4.1"
serde = { version = "1.0.136", features = ["derive"] }
im-rc = "15.0.0"
anyhow = "1.0.53"
serde_json = "1.0.79"
rand = { version = "0.8.4", features = ["small_rng"] }
tokio = { version = "1.16.1", features = ["full"] }
reqwest = { version = "0.11.9", features = ["json"] }
fern = { version = "0.6.0", features = ["colored"] }
thiserror = "1.0.30"
env_logger = "0.9.0"
simple_logger = "4.0.0"
# [dev-dependencies]
# dioxus = { path = "./packages/dioxus" }
# dioxus-desktop = { path = "./packages/desktop" }
# dioxus-ssr = { path = "./packages/ssr" }
# dioxus-router = { path = "./packages/router" }
# fermi = { path = "./packages/fermi" }
# futures-util = "0.3.21"
# log = "0.4.14"
# num-format = "0.4.0"
# separator = "0.4.1"
# serde = { version = "1.0.136", features = ["derive"] }
# im-rc = "15.0.0"
# anyhow = "1.0.53"
# serde_json = "1.0.79"
# rand = { version = "0.8.4", features = ["small_rng"] }
# tokio = { version = "1.16.1", features = ["full"] }
# reqwest = { version = "0.11.9", features = ["json"] }
# fern = { version = "0.6.0", features = ["colored"] }
# thiserror = "1.0.30"
# env_logger = "0.9.0"
# simple_logger = "4.0.0"
[profile.release]
opt-level = 3
lto = true
debug = true
# [profile.release]
# opt-level = 3
# lto = true
# debug = true
+1 -1
View File
@@ -102,7 +102,7 @@ pub fn fmt_file(contents: &str) -> Vec<FormattedBlock> {
pub fn write_block_out(body: CallBody) -> Option<String> {
let mut buf = Buffer {
src: vec![],
src: vec!["".to_string()],
indent: 0,
..Buffer::default()
};
-13
View File
@@ -1,13 +0,0 @@
use html_parser::Dom;
fn main() {
let html = "hello world!";
let dom = Dom::parse(html).unwrap();
let body = rsx_rosetta::convert_from_html(dom);
let out = dioxus_autofmt::write_block_out(body).unwrap();
dbg!(out);
}
-31
View File
@@ -1,31 +0,0 @@
use dioxus_rsx::{BodyNode, CallBody, IfmtInput};
use html_parser::{Dom, Node};
use proc_macro2::Span;
use syn::LitStr;
#[derive(thiserror::Error, Debug)]
pub enum ConvertError {}
pub fn convert_from_html(html: Dom) -> CallBody {
let roots = html
.children
.into_iter()
.map(|f| create_body_node_from_node(f))
.filter_map(|f| f)
.collect();
CallBody { roots }
}
fn create_body_node_from_node(node: Node) -> Option<BodyNode> {
let res = match node {
Node::Text(text) => BodyNode::Text(IfmtInput {
source: Some(LitStr::new(text.as_str(), Span::call_site())),
segments: vec![],
}),
Node::Element(_) => todo!(),
Node::Comment(_) => return None,
};
Some(res)
}
@@ -12,7 +12,7 @@ html_parser = "0.6.3"
proc-macro2 = "1.0.49"
quote = "1.0.23"
syn = { version = "1.0.107", features = ["full"] }
thiserror = "1.0.38"
convert_case = "0.5.0"
# [features]
# default = ["html"]
File renamed without changes.
+24
View File
@@ -0,0 +1,24 @@
use html_parser::Dom;
fn main() {
let html = r#"
<div>
<div class="asd">hello world!</div>
<div id="asd">hello world!</div>
<div id="asd">hello world!</div>
<div for="asd">hello world!</div>
<div async="asd">hello world!</div>
<div LargeThing="asd">hello world!</div>
<ai-is-awesome>hello world!</ai-is-awesome>
</div>
"#
.trim();
let dom = Dom::parse(html).unwrap();
let body = rsx_rosetta::convert_from_html(dom);
let out = dioxus_autofmt::write_block_out(body).unwrap();
println!("{}", out);
}
+92
View File
@@ -0,0 +1,92 @@
use dioxus_rsx::{BodyNode, CallBody, Element, ElementAttr, ElementAttrNamed, IfmtInput};
pub use html_parser::{Dom, Node};
use proc_macro2::{Ident, Span};
use syn::LitStr;
pub fn convert_from_html(dom: Dom) -> CallBody {
CallBody {
roots: dom
.children
.into_iter()
.map(|f| create_body_node_from_node(f))
.filter_map(|f| f)
.collect(),
}
}
fn create_body_node_from_node(node: Node) -> Option<BodyNode> {
match node {
Node::Text(text) => Some(BodyNode::Text(ifmt_from_text(text))),
Node::Element(el) => {
use convert_case::{Case, Casing};
let el_name = el.name.to_case(Case::Snake);
let el_name = Ident::new(el_name.as_str(), Span::call_site());
let mut attributes: Vec<_> = el
.attributes
.into_iter()
.map(|(name, value)| {
let ident = if matches!(name.as_str(), "for" | "async" | "type" | "as") {
Ident::new_raw(name.as_str(), Span::call_site())
} else {
let new_name = name.to_case(Case::Snake);
Ident::new(new_name.as_str(), Span::call_site())
};
ElementAttrNamed {
attr: ElementAttr::AttrText {
name: ident,
value: ifmt_from_text(value.unwrap_or("false".to_string())),
},
el_name: el_name.clone(),
}
})
.collect();
let class = el.classes.join(" ");
if !class.is_empty() {
attributes.push(ElementAttrNamed {
attr: ElementAttr::AttrText {
name: Ident::new("class", Span::call_site()),
value: ifmt_from_text(class),
},
el_name: el_name.clone(),
});
}
if let Some(id) = el.id {
attributes.push(ElementAttrNamed {
attr: ElementAttr::AttrText {
name: Ident::new("id", Span::call_site()),
value: ifmt_from_text(id),
},
el_name: el_name.clone(),
});
}
let children = el
.children
.into_iter()
.map(|f| create_body_node_from_node(f))
.filter_map(|f| f)
.collect();
Some(BodyNode::Element(Element {
name: el_name,
children,
attributes,
_is_static: false,
key: None,
}))
}
Node::Comment(_) => None,
}
}
fn ifmt_from_text(text: String) -> IfmtInput {
IfmtInput {
source: Some(LitStr::new(text.as_str(), Span::call_site())),
segments: vec![],
}
}