Skip to content

Commit

Permalink
Support inner html
Browse files Browse the repository at this point in the history
  • Loading branch information
chinedufn committed May 18, 2019
1 parent d2e3b3e commit e41857e
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 35 deletions.
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- [Writing html!](./html-macro/html-macro.md)
- [Compile Time Errors](./html-macro/compile-time-errors.md)
- [Working with Text](./html-macro/text/README.md)
- [Setting Inner HTML](./html-macro/setting-inner-html/README.md)
- [Virtual DOM](./virtual-dom/README.md)
- [Unit Testing your Views](./virtual-dom/unit-testing-views.md)
- [Server Side Rendering (SSR)](./views/server-side-rendering/README.md)
Expand Down
16 changes: 16 additions & 0 deletions book/src/html-macro/setting-inner-html/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Setting Inner HTML

You'll sometimes want to use a string of HTML in order to set the child nodes for an element.

For example, if you're creating a tooltip component you might want to be able to support setting tooltips as such:

<div data-tip="Hello <strong>World!</strong>"></div>

You can use the `unsafe_inner_html` attribute for this purpose.

Note that it is called `unsafe` because it can poentially expose your application to cross side scripting attacks if your application
trusts arbitrary un-escaped HTML strings that are provided by users.

```rust
{{#bookimport ../../../../crates/virtual-dom-rs/tests/create_element.rs@inner-html}}
```
2 changes: 1 addition & 1 deletion crates/router-rs-macro-test/src/book_example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn route_data_and_param(id: u16, state: Provided<SomeState>, meal: Meal) -> Virt
}
}

fn download_some_data (id: u16, state: Provided<SomeState>, meal: Meal) {
fn download_some_data(id: u16, state: Provided<SomeState>, meal: Meal) {
// Check state to see if we've already downloaded data ...
// If not - download the data that we need
}
Expand Down
9 changes: 6 additions & 3 deletions crates/router-rs-macro-test/src/on_visit.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use router_rs::prelude::*;
use std::sync::atomic::{AtomicBool, Ordering, AtomicUsize};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use virtual_dom_rs::prelude::VirtualNode;

static mut VISITED: AtomicBool = AtomicBool::new(false);
Expand Down Expand Up @@ -57,7 +57,7 @@ fn route_param_and_data(id: u16, state: Provided<SomeState>) -> VirtualNode {
VirtualNode::Text("".into())
}

fn set_id (id: u16, state: Provided<SomeState>) {
fn set_id(id: u16, state: Provided<SomeState>) {
unsafe {
*ID.get_mut() = id as usize;
}
Expand All @@ -74,7 +74,10 @@ fn visit_params_data() {
assert_eq!(ID.load(Ordering::SeqCst), 0);
}

router.matching_routerhandler("/users/5").unwrap().on_visit("/users/5");
router
.matching_routerhandler("/users/5")
.unwrap()
.on_visit("/users/5");

unsafe {
assert_eq!(ID.load(Ordering::SeqCst), 5);
Expand Down
21 changes: 21 additions & 0 deletions crates/virtual-dom-rs/tests/create_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
//! To run all tests in this file:
//!
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element
//!
//! ---
//!
//! To run a single test:
//!
//! wasm-pack test crates/virtual-dom-rs --chrome --headless -- --test create_element nested_divs

#![feature(proc_macro_hygiene)]

Expand Down Expand Up @@ -76,3 +82,18 @@ fn click_event() {

assert_eq!(*clicked, Cell::new(true));
}

// @book start inner-html
#[wasm_bindgen_test]
fn inner_html() {
let div = html! {
<div
unsafe_inner_html="<span>hi</span>"
>
</div>
};
let div: Element = div.create_dom_node().node.unchecked_into();

assert_eq!(div.inner_html(), "<span>hi</span>");
}
// @book end inner-html
40 changes: 26 additions & 14 deletions crates/virtual-node/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ impl VElement {
let mut closures = HashMap::new();

self.attrs.iter().for_each(|(name, value)| {
if name == "unsafe_inner_html" {
element.set_inner_html(value);

return;
}

element
.set_attribute(name, value)
.expect("Set element attribute in create element");
Expand Down Expand Up @@ -578,18 +584,24 @@ mod tests {
assert_eq!(&node.to_string(), "<br>");
}

// TODO: Use html_macro as dev dependency and uncomment
// #[test]
// fn to_string() {
// let node = html! {
// <div id="some-id", !onclick=|_ev| {},>
// <span>
// { "Hello world" }
// </span>
// </div>
// };
// let expected = r#"<div id="some-id"><span>Hello world</span></div>"#;
//
// assert_eq!(node.to_string(), expected);
// }
#[test]
fn to_string() {
let mut node = VirtualNode::Element(VElement::new("div"));
node.as_velement_mut()
.unwrap()
.attrs
.insert("id".into(), "some-id".into());

let mut child = VirtualNode::Element(VElement::new("span"));

let mut text = VirtualNode::Text(VText::new("Hello world"));

child.as_velement_mut().unwrap().children.push(text);

node.as_velement_mut().unwrap().children.push(child);

let expected = r#"<div id="some-id"><span>Hello world</span></div>"#;

assert_eq!(node.to_string(), expected);
}
}
3 changes: 2 additions & 1 deletion examples/isomorphic/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ fn download_contributors_json(store: Provided<Rc<RefCell<Store>>>) {

web_sys::window()
.unwrap()
.request_animation_frame(raf_closure.as_ref().unchecked_ref()).unwrap();
.request_animation_frame(raf_closure.as_ref().unchecked_ref())
.unwrap();

// TODO: We don't want to repeatedly forget this closure and should instead figure out a place
// to store it.
Expand Down
6 changes: 3 additions & 3 deletions examples/isomorphic/app/src/state/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ impl State {
match msg {
Msg::Click => self.increment_click(),
Msg::SetPath(path) => self.set_path(path.to_string()),
Msg::SetContributorsJson(json) => {
self.contributors = Some(json.into_serde().unwrap());
},
Msg::SetContributorsJson(json) => {
self.contributors = Some(json.into_serde().unwrap());
}
Msg::InitiatedContributorsDownload => {
self.has_initiated_contributors_download = true;
}
Expand Down
2 changes: 1 addition & 1 deletion examples/isomorphic/app/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl Store {
if let Some(after_route) = &self.after_route {
after_route(path.as_str());
}
},
}
_ => self.state.msg(msg),
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ pub struct NavBarItemView {
}

impl NavBarItemView {
pub fn new(
path: &'static str,
text: &'static str,
style: &'static str
) -> NavBarItemView {
pub fn new(path: &'static str, text: &'static str, style: &'static str) -> NavBarItemView {
NavBarItemView { path, text, style }
}
}
Expand Down
10 changes: 3 additions & 7 deletions examples/isomorphic/client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ impl Client {
}));

app.store.borrow_mut().set_after_route(Box::new(|new_path| {
history()
.push_state_with_url(&JsValue::null(), "Rust Web App", Some(new_path));
history().push_state_with_url(&JsValue::null(), "Rust Web App", Some(new_path));
}));

let store = Rc::clone(&app.store);
Expand All @@ -67,8 +66,7 @@ impl Client {
};
let on_popstate = Box::new(on_popstate) as Box<FnMut(_)>;
let mut on_popstate = Closure::wrap(on_popstate);
window()
.set_onpopstate(Some(on_popstate.as_ref().unchecked_ref()));
window().set_onpopstate(Some(on_popstate.as_ref().unchecked_ref()));
on_popstate.forget();

let root_node = document()
Expand Down Expand Up @@ -141,9 +139,7 @@ fn history() -> web_sys::History {
}

fn location() -> web_sys::Location {
document()
.location()
.unwrap()
document().location().unwrap()
}

fn hostname() -> String {
Expand Down

0 comments on commit e41857e

Please sign in to comment.