feat: complete html to rsx rosetta
This commit is contained in:
1 parent
d22577082c
commit
bc3cf6501c
8 files changed
+159
-87
No files matched your search
+41
-41
@@ -18,49 +18,49 @@ members = [
|
|||||||
"packages/tui",
|
"packages/tui",
|
||||||
"packages/native-core",
|
"packages/native-core",
|
||||||
"packages/native-core-macro",
|
"packages/native-core-macro",
|
||||||
|
"packages/rsx-rosetta",
|
||||||
"docs/guide",
|
"docs/guide",
|
||||||
"packages/html-to-rsx"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# This is a "virtual package"
|
# # This is a "virtual package"
|
||||||
# It is not meant to be published, but is used so "cargo run --example XYZ" works properly
|
# # It is not meant to be published, but is used so "cargo run --example XYZ" works properly
|
||||||
[package]
|
# [package]
|
||||||
name = "dioxus-examples"
|
# name = "dioxus-examples"
|
||||||
version = "0.0.0"
|
# version = "0.0.0"
|
||||||
authors = ["Jonathan Kelley"]
|
# authors = ["Jonathan Kelley"]
|
||||||
edition = "2021"
|
# edition = "2021"
|
||||||
description = "Top level crate for the Dioxus repository"
|
# description = "Top level crate for the Dioxus repository"
|
||||||
license = "MIT OR Apache-2.0"
|
# license = "MIT OR Apache-2.0"
|
||||||
repository = "https://github.com/DioxusLabs/dioxus/"
|
# repository = "https://github.com/DioxusLabs/dioxus/"
|
||||||
homepage = "https://dioxuslabs.com"
|
# homepage = "https://dioxuslabs.com"
|
||||||
documentation = "https://dioxuslabs.com"
|
# documentation = "https://dioxuslabs.com"
|
||||||
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
# keywords = ["dom", "ui", "gui", "react", "wasm"]
|
||||||
rust-version = "1.60.0"
|
# rust-version = "1.60.0"
|
||||||
publish = false
|
# publish = false
|
||||||
|
|
||||||
[dev-dependencies]
|
# [dev-dependencies]
|
||||||
dioxus = { path = "./packages/dioxus" }
|
# dioxus = { path = "./packages/dioxus" }
|
||||||
dioxus-desktop = { path = "./packages/desktop" }
|
# dioxus-desktop = { path = "./packages/desktop" }
|
||||||
dioxus-ssr = { path = "./packages/ssr" }
|
# dioxus-ssr = { path = "./packages/ssr" }
|
||||||
dioxus-router = { path = "./packages/router" }
|
# dioxus-router = { path = "./packages/router" }
|
||||||
fermi = { path = "./packages/fermi" }
|
# fermi = { path = "./packages/fermi" }
|
||||||
futures-util = "0.3.21"
|
# futures-util = "0.3.21"
|
||||||
log = "0.4.14"
|
# log = "0.4.14"
|
||||||
num-format = "0.4.0"
|
# num-format = "0.4.0"
|
||||||
separator = "0.4.1"
|
# separator = "0.4.1"
|
||||||
serde = { version = "1.0.136", features = ["derive"] }
|
# serde = { version = "1.0.136", features = ["derive"] }
|
||||||
im-rc = "15.0.0"
|
# im-rc = "15.0.0"
|
||||||
anyhow = "1.0.53"
|
# anyhow = "1.0.53"
|
||||||
serde_json = "1.0.79"
|
# serde_json = "1.0.79"
|
||||||
rand = { version = "0.8.4", features = ["small_rng"] }
|
# rand = { version = "0.8.4", features = ["small_rng"] }
|
||||||
tokio = { version = "1.16.1", features = ["full"] }
|
# tokio = { version = "1.16.1", features = ["full"] }
|
||||||
reqwest = { version = "0.11.9", features = ["json"] }
|
# reqwest = { version = "0.11.9", features = ["json"] }
|
||||||
fern = { version = "0.6.0", features = ["colored"] }
|
# fern = { version = "0.6.0", features = ["colored"] }
|
||||||
thiserror = "1.0.30"
|
# thiserror = "1.0.30"
|
||||||
env_logger = "0.9.0"
|
# env_logger = "0.9.0"
|
||||||
simple_logger = "4.0.0"
|
# simple_logger = "4.0.0"
|
||||||
|
|
||||||
[profile.release]
|
# [profile.release]
|
||||||
opt-level = 3
|
# opt-level = 3
|
||||||
lto = true
|
# lto = true
|
||||||
debug = true
|
# debug = true
|
||||||
@@ -102,7 +102,7 @@ pub fn fmt_file(contents: &str) -> Vec<FormattedBlock> {
|
|||||||
|
|
||||||
pub fn write_block_out(body: CallBody) -> Option<String> {
|
pub fn write_block_out(body: CallBody) -> Option<String> {
|
||||||
let mut buf = Buffer {
|
let mut buf = Buffer {
|
||||||
src: vec![],
|
src: vec!["".to_string()],
|
||||||
indent: 0,
|
indent: 0,
|
||||||
..Buffer::default()
|
..Buffer::default()
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
|
||||||
}
|
|
||||||
@@ -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"
|
proc-macro2 = "1.0.49"
|
||||||
quote = "1.0.23"
|
quote = "1.0.23"
|
||||||
syn = { version = "1.0.107", features = ["full"] }
|
syn = { version = "1.0.107", features = ["full"] }
|
||||||
thiserror = "1.0.38"
|
convert_case = "0.5.0"
|
||||||
|
|
||||||
# [features]
|
# [features]
|
||||||
# default = ["html"]
|
# default = ["html"]
|
||||||
File renamed without changes.
@@ -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);
|
||||||
|
}
|
||||||
@@ -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![],
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user