Skip to content

Tweak bootstrap order so that main_el_vdom is initialized first. #274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 1, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 38 additions & 30 deletions src/vdom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,48 +195,43 @@ impl<Ms, Mdl, ElC: View<Ms> + 'static, GMs: 'static> App<Ms, Mdl, ElC, GMs> {
}
}

/// App initialization: Collect its fundamental components, setup, and perform
/// an initial render.
pub fn run(self) -> Self {
self.process_cmd_and_msg_queue(
self.cfg
.initial_orders
.replace(None)
.expect("initial_orders should be set in AppBuilder::finish")
.effects,
);
// Our initial render. Can't initialize in new due to mailbox() requiring self.
fn bootstrapped_vdom(&self) -> El<Ms> {
// "new" name is for consistency with `update` function.
// this section parent is a placeholder, so we can iterate over children
// in a way consistent with patching code.
let mut new = El::empty(dom_types::Tag::Section);
new.children = (self.cfg.view)(self.data.model.borrow().as_ref().unwrap()).els();
let mut new = El::empty(dom_types::Tag::Placeholder);

self.setup_window_listeners();
patch::setup_input_listeners(&mut new);
patch::attach_listeners(&mut new, &self.mailbox());

let mut new_node = Node::Element(new);

websys_bridge::assign_ws_nodes(&util::document(), &mut new_node);

if let Node::Element(mut new) = new_node {
// Attach all top-level elements to the mount point: This is where our initial render occurs.
for child in &mut new.children {
match child {
Node::Element(child_el) => {
websys_bridge::attach_el_and_children(child_el, &self.cfg.mount_point);
patch::attach_listeners(child_el, &self.mailbox());
}
Node::Text(top_child_text) => {
websys_bridge::attach_text_node(top_child_text, &self.cfg.mount_point);
}
Node::Empty => (),
websys_bridge::assign_ws_nodes_to_el(&util::document(), &mut new);

// Attach all top-level elements to the mount point.
for child in &mut new.children {
match child {
Node::Element(child_el) => {
websys_bridge::attach_el_and_children(child_el, &self.cfg.mount_point);
patch::attach_listeners(child_el, &self.mailbox());
}
Node::Text(top_child_text) => {
websys_bridge::attach_text_node(top_child_text, &self.cfg.mount_point);
}
Node::Empty => (),
}
self.data.main_el_vdom.replace(Some(new));
}

new
}

/// App initialization: Collect its fundamental components, setup, and perform
/// an initial render.
pub fn run(self) -> Self {
// Bootstrap the virtual DOM.
self.data
.main_el_vdom
.replace(Some(self.bootstrapped_vdom()));

// Update the state on page load, based
// on the starting URL. Must be set up on the server as well.
if let Some(routes) = *self.data.routes.borrow() {
Expand All @@ -256,6 +251,19 @@ impl<Ms, Mdl, ElC: View<Ms> + 'static, GMs: 'static> App<Ms, Mdl, ElC, GMs> {
);
routing::setup_link_listener(enclose!((self => s) move |msg| s.update(msg)), routes);
}

// Our initial render. Can't initialize in new due to mailbox() requiring self.
self.process_cmd_and_msg_queue(
self.cfg
.initial_orders
.replace(None)
.expect("initial_orders should be set in AppBuilder::finish")
.effects,
);
// TODO: In the future, only run the following line if the above statement does not
// TODO: call `rerender_vdom` for efficiency.
self.rerender_vdom();

self
}

Expand Down
13 changes: 7 additions & 6 deletions src/websys_bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,19 @@ fn set_style(el_ws: &web_sys::Node, style: &dom_types::Style) {
.expect("Problem setting style");
}

pub(crate) fn assign_ws_nodes_to_el<Ms>(document: &Document, el: &mut El<Ms>) {
el.node_ws = Some(make_websys_el(el, document));
for mut child in &mut el.children {
assign_ws_nodes(document, &mut child);
}
}
/// Recursively create `web_sys::Node`s, and place them in the vdom Nodes' fields.
pub(crate) fn assign_ws_nodes<Ms>(document: &Document, node: &mut Node<Ms>)
where
Ms: 'static,
{
match node {
Node::Element(el) => {
el.node_ws = Some(make_websys_el(el, document));
for mut child in &mut el.children {
assign_ws_nodes(document, &mut child);
}
}
Node::Element(el) => assign_ws_nodes_to_el(document, el),
Node::Text(text) => {
text.node_ws = Some(
document
Expand Down