Skip to content

Commit

Permalink
Add docs for VNode::html_from_raw
Browse files Browse the repository at this point in the history
  • Loading branch information
hamza1311 committed Aug 24, 2022
1 parent 609e3c5 commit 4a912be
Showing 1 changed file with 86 additions and 85 deletions.
171 changes: 86 additions & 85 deletions packages/yew/src/virtual_dom/vnode.rs
Expand Up @@ -46,69 +46,99 @@ impl VNode {
self.key().is_some()
}

#[cfg(any(feature = "csr", feature = "hydration"))]
/// Create a [`VNode`] from a string of HTML
///
/// # Behavior in browser
///
/// In the browser, this function creates an element, sets the passed HTML to its `innerHTML`
/// and returns a [`VNode::VRef`] of it
///
/// # Behavior on server
///
/// Since there's no DOM available on the server, the passed HTML is parsed using the
/// [`html_parser`](https://docs.rs/html_parser/0.6.3/html_parser/) crate. A VNode is created
/// from the parsed HTML
///
/// # Example
///
/// ```rust
/// # use yew::virtual_dom::VNode;
/// # use yew::html;
/// # fn _main() {
/// let parsed = VNode::from_raw_html("<div>content</div>");
/// let _: VNode = html! {
/// <div>
/// {parsed}
/// <div>
/// }
/// # }
/// ```
pub fn from_raw_html(html: &str) -> Self {
let div = gloo::utils::document().create_element("div").unwrap();
div.set_inner_html(html);
VNode::VRef(div.into())
}

#[cfg(feature = "ssr")]
pub fn from_raw_html(html: &str) -> Self {
use html_parser::{Dom, Node};
#[cfg(any(feature = "csr", feature = "hydration"))]
fn inner(html: &str) -> VNode {
let div = gloo::utils::document().create_element("div").unwrap();
div.set_inner_html(html);
VNode::VRef(div.into())
}

use super::{ApplyAttributeAs, Attributes};
use crate::{AttrValue, Classes};
fn dom_node_to_vnode(node: Node) -> VNode {
match node {
Node::Text(text) => VNode::from(VText::new(text)),
Node::Element(element) => {
let mut tag = VTag::new(element.name);
if !element.attributes.is_empty() {
let attributes = element
.attributes
.into_iter()
.map(|(key, value)| {
(
AttrValue::from(key),
#[cfg(feature = "ssr")]
fn inner(html: &str) -> VNode {
use html_parser::{Dom, Node};

use super::{ApplyAttributeAs, Attributes};
use crate::{AttrValue, Classes};
fn dom_node_to_vnode(node: Node) -> VNode {
match node {
Node::Text(text) => VNode::from(VText::new(text)),
Node::Element(element) => {
let mut tag = VTag::new(element.name);
if !element.attributes.is_empty() {
let attributes = element
.attributes
.into_iter()
.map(|(key, value)| {
(
AttrValue::from(value.unwrap_or_default()),
ApplyAttributeAs::Attribute,
),
)
})
.collect();
tag.set_attributes(Attributes::IndexMap(attributes));
}
if let Some(id) = element.id {
tag.add_attribute("id", id)
AttrValue::from(key),
(
AttrValue::from(value.unwrap_or_default()),
ApplyAttributeAs::Attribute,
),
)
})
.collect();
tag.set_attributes(Attributes::IndexMap(attributes));
}
if let Some(id) = element.id {
tag.add_attribute("id", id)
}
if !element.classes.is_empty() {
tag.add_attribute("class", Classes::from(element.classes).to_string())
};
tag.add_children(
element
.children
.into_iter()
.map(dom_node_to_vnode)
.collect::<Vec<_>>(),
);
VNode::from(tag)
}
if !element.classes.is_empty() {
tag.add_attribute("class", Classes::from(element.classes).to_string())
};
tag.add_children(
element
.children
.into_iter()
.map(dom_node_to_vnode)
.collect::<Vec<_>>(),
);
VNode::from(tag)
Node::Comment(_) => VNode::default(),
}
Node::Comment(_) => VNode::default(),
}
}

let dom = Dom::parse(html).map(|it| {
let vnodes = it
.children
.into_iter()
.map(dom_node_to_vnode)
.collect::<Vec<_>>();
VNode::from(VList::with_children(vnodes, None))
});
// error handling??
dom.unwrap()
let dom = Dom::parse(html).map(|it| {
let vnodes = it
.children
.into_iter()
.map(dom_node_to_vnode)
.collect::<Vec<_>>();
VNode::from(VList::with_children(vnodes, None))
});
// error handling??
dom.unwrap()
}
inner(html)
}
}

Expand Down Expand Up @@ -267,32 +297,3 @@ mod feat_ssr {
}
}
}

#[cfg(test)]
mod tests {
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_test::wasm_bindgen_test as test;
#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);

use super::*;
use crate::html;

const HTML: &str = r#"<div><a>a link</a><button>click me</button></div><p>paragraph</p>"#;
// const HTML: &str = r#"<div><a href="https://yew.rs">a link</a><button>click me</button></div><p>paragraph</p>"#;

#[test]
fn from_raw_html_works() {
let vnode = html! {
<><div>{"div"}</div></>
};

eprintln!("{:#?}", vnode);

let from_raw = VNode::from_raw_html("<div>div</div>");
eprintln!();
eprintln!("{:#?}", from_raw);

assert_eq!(vnode, from_raw);
}
}

0 comments on commit 4a912be

Please sign in to comment.