Skip to content

Commit

Permalink
Merge pull request #32 from chinedufn/web-sys
Browse files Browse the repository at this point in the history
Migrate to web-sys
  • Loading branch information
chinedufn authored Sep 18, 2018
2 parents 66583f2 + c393fa8 commit 17a6abf
Show file tree
Hide file tree
Showing 21 changed files with 405 additions and 229 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ members = [
"examples/isomorphic/server",
"examples/unit-testing-components",
"examples/css-in-rust",
"percy-webapis",
"tests/jsdom",
"tests/test-css-rs",
"tests/test-css-rs-fixture",
Expand Down
2 changes: 2 additions & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
- [Unit Testing your Views](./unit-testing-views.md)
- [CSS in Rust](./css-in-rust.md)
- [Contributing](./contributing.md)
- [Internal Design](./contributing/internal-design/README.md)
- [Handling text siblings](./contributing/internal-design/sibling-text-nodes.md)
41 changes: 19 additions & 22 deletions book/src/contributing.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Contributing

## Making Changes to the Percy Codebase

1. Rust Nightly.

```sh
rustup default nightly
rustup target add wasm32-unknown-unknown
```
2. [Install Node.js 10+](https://github.com/creationix/nvm#installation) since some of our tests use Node.js.

3. Download the project and make sure that you can run the test suite

```sh
git clone https://github.com/chinedufn/percy
cd percy
npm install
./test.sh
```

## Types of Contributions

There are three main types of contributions to `Percy`, all of which are equally important.
Expand Down Expand Up @@ -58,25 +77,3 @@ fix and/or suggest approaches for.
If you have an idea for something that you can build with `Percy` then get started. Feel
free to open up an issue with any questions or thoughts that you might have. Also open
issues / PRs as you run into problems / annoyances.

### Refactoring Code and Tests

lorem ipsum TODO

## Making Changes to the Percy Codebase

1. Rust Nightly.

```sh
rustup default nightly
rustup target add wasm32-unknown-unknown
```
2. [Install Node.js 10+](https://github.com/creationix/nvm#installation) since some of our tests use Node.js.
3. Download the project and make sure that you can run the test suite

```sh
git clone https://github.com/chinedufn/percy
cd percy
npm install
./test.sh
```
3 changes: 3 additions & 0 deletions book/src/contributing/internal-design/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Design of `percy`

This section is intended to be a deep dive into how `percy`'s different internal pieces work today.
42 changes: 42 additions & 0 deletions book/src/contributing/internal-design/sibling-text-nodes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Sibling text nodes

If a browser sees two text nodes next to each other it will combine them into one.

For example, when you have a component that looks like this:

```rust
let sibling_text_nodes = html! { <div> {"Hello" "World" } </div> };
```

A browser will end up turning it into something like this

```html
<div>Hello World</div>
```

The `textContent` of the div in the browser is now "Hello World".

If we did not work around this behavior we wouldn't be able to patch the DOM when two text nodes are next to each other.
We'd have no way of knowing how to find the original, individual strings that we wanted to render.

To get around this here's what we actually end up rendering:

```html
<div>Hello <!--ptns-->World</div>
```

Note the new `<!--ptns-->` comment node. Here's what `virtual_dom_rs`'s `createElement()` method ended up doing:

1. Saw the "Hello" virtual text and appended a real Text node into the real DOM `<div>`
2. Saw the "World" virtual text and saw that the previous element was also a virtual text node
3. Appended a `<!--ptns>` real comment element into the `<div>`
4. Appended a real "World" Text node into the `<div>`

If we later wanted to patch the DOM with a new component

```
let sibling_text_nodes = html! { <div> {"Hello" "NEW_TEXT" } </div> };
```

Our `virtual_dom_rs` patch function would be able to find the old "World" text node since we've ensured that it
did not get merged in with any other text nodes.
18 changes: 1 addition & 17 deletions examples/isomorphic/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,26 @@ extern crate serde_json;

use std::cell::RefCell;
use std::rc::Rc;
use virtual_dom_rs::virtual_node::VirtualNode;
pub use virtual_dom_rs::virtual_node::VirtualNode;

mod state;
pub use state::*;

pub use virtual_dom_rs::percy_webapis::*;

pub struct App {
pub state: Rc<RefCell<State>>,
previous_vdom: Option<VirtualNode>,
}

impl App {
pub fn new(count: u32) -> App {
App {
state: Rc::new(RefCell::new(State::new(count))),
previous_vdom: None,
}
}

// TODO: Just use `new(config: AppConfig)` and pass in state json Option
pub fn from_state_json(json: &str) -> App {
App {
state: Rc::new(RefCell::new(State::from_json(json))),
previous_vdom: None,
}
}
}
Expand All @@ -55,17 +50,6 @@ impl App {
</div>
}
}

pub fn update_dom(&mut self, root_node: &Element) {
let mut new_vdom = self.render();

if let Some(ref previous_vdom) = self.previous_vdom {
let patches = virtual_dom_rs::diff(&previous_vdom, &mut new_vdom);
virtual_dom_rs::patch(&root_node, &patches);
}

self.previous_vdom = Some(new_vdom);
}
}

#[cfg(test)]
Expand Down
18 changes: 16 additions & 2 deletions examples/isomorphic/client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,21 @@ crate-type = ["cdylib"]

[dependencies]
isomorphic-app = { path = "../app" }
virtual-dom-rs = { path = "../../../virtual-dom-rs" }

[dependencies.wasm-bindgen]
version = "0.2"
features = ["default", "spans"]
git = "https://github.com/rustwasm/wasm-bindgen"
features = ["default", "nightly"]

[dependencies.web-sys]
git = "https://github.com/rustwasm/wasm-bindgen"
features = [
"Document",
"Element",
"EventTarget",
"Node",
"NodeList",
"Text",
"Window",
"HtmlCollection",
]
27 changes: 23 additions & 4 deletions examples/isomorphic/client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

extern crate virtual_dom_rs;

extern crate web_sys;
use web_sys::Element;

extern crate isomorphic_app;
use isomorphic_app::App;
use isomorphic_app::Element;
use isomorphic_app::VirtualNode;

#[wasm_bindgen(module = "./src/client.js")]
extern "C" {
Expand All @@ -14,6 +19,7 @@ extern "C" {
pub struct Client {
app: App,
root_node: Option<Element>,
previous_vdom: Option<VirtualNode>,
}

#[wasm_bindgen]
Expand All @@ -31,18 +37,31 @@ impl Client {
Client {
app,
root_node: None,
previous_vdom: None,
}
}

pub fn set_root_node(&mut self, root_node: Element) {
self.root_node = Some(root_node);
}

pub fn render(&self) -> Element {
self.app.render().create_element()
pub fn render(&mut self) -> Element {
let html = self.app.render();

self.previous_vdom = Some(html);

self.previous_vdom.as_ref().unwrap().create_element()
}

pub fn update_dom(&mut self) {
self.app.update_dom(&self.root_node.as_ref().unwrap())
let mut new_vdom = self.app.render();

if let Some(ref previous_vdom) = self.previous_vdom {
let patches = virtual_dom_rs::diff(&previous_vdom, &mut new_vdom);
let root_node = self.root_node.take().unwrap();
virtual_dom_rs::patch(root_node, &patches);
}

self.previous_vdom = Some(new_vdom);
}
}
10 changes: 8 additions & 2 deletions examples/unit-testing-components/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ fn full_water_bottle() -> VirtualNode {

#[allow(unused)]
fn struggling_water_bottle(percent_full: f32) -> VirtualNode {
let message = format!("Please fill me up :( I am only {} percent full :(", percent_full);
let message = format!(
"Please fill me up :( I am only {} percent full :(",
percent_full
);

html! {
<div label="struggle-water",> { message } </div>
Expand All @@ -49,7 +52,10 @@ mod tests {
let struggle_water = water_bottle_view(0.2587);

assert_eq!(
struggle_water.children.as_ref().unwrap()[0].text.as_ref().unwrap(),
struggle_water.children.as_ref().unwrap()[0]
.text
.as_ref()
.unwrap(),
"Please fill me up :( I am only 0.2587 percent full :("
)
}
Expand Down
12 changes: 0 additions & 12 deletions percy-webapis/Cargo.toml

This file was deleted.

100 changes: 0 additions & 100 deletions percy-webapis/src/lib.rs

This file was deleted.

2 changes: 1 addition & 1 deletion test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

cd $(git rev-parse --show-toplevel)

cargo build --all && \ # Make sure examples compile
cargo build --all && # Make sure examples compile
cargo test --all && npm run test
Loading

0 comments on commit 17a6abf

Please sign in to comment.