Skip to content

Commit

Permalink
work on naming: ancestor -> bundle
Browse files Browse the repository at this point in the history
  • Loading branch information
WorldSEnder committed Jan 5, 2022
1 parent 031976c commit bcde660
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 107 deletions.
12 changes: 6 additions & 6 deletions packages/yew/src/dom_bundle/attributes.rs
Expand Up @@ -47,8 +47,8 @@ impl<T: AccessValue> Apply for Value<T> {
self
}

fn apply_diff(self, el: &Self::Element, ancestor: &mut Self) {
match (&self.0, &ancestor.0) {
fn apply_diff(self, el: &Self::Element, bundle: &mut Self) {
match (&self.0, &bundle.0) {
(Some(new), Some(_)) => {
// Refresh value from the DOM. It might have changed.
if new.as_ref() != el.value() {
Expand Down Expand Up @@ -96,8 +96,8 @@ pub(crate) trait Apply {
/// Apply contained values to [Element] with no ancestor
fn apply(self, el: &Self::Element) -> Self::Bundle;

/// Apply diff between [self] and `ancestor` to [Element].
fn apply_diff(self, el: &Self::Element, ancestor: &mut Self::Bundle);
/// Apply diff between [self] and `bundle` to [Element].
fn apply_diff(self, el: &Self::Element, bundle: &mut Self::Bundle);
}

/// Fields specific to
Expand Down Expand Up @@ -159,12 +159,12 @@ impl Apply for InputFields {
self
}

fn apply_diff(self, el: &Self::Element, ancestor: &mut Self) {
fn apply_diff(self, el: &Self::Element, bundle: &mut Self) {
// IMPORTANT! This parameter has to be set every time
// to prevent strange behaviour in the browser when the DOM changes
el.set_checked(self.checked);

self.value.apply_diff(el, &mut ancestor.value);
self.value.apply_diff(el, &mut bundle.value);
}
}

Expand Down
14 changes: 7 additions & 7 deletions packages/yew/src/dom_bundle/bcomp.rs
Expand Up @@ -160,18 +160,18 @@ impl Reconcilable for VComp {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
let bcomp = match ancestor {
// If the ancestor is the same type, reuse it and update its properties
let bcomp = match bundle {
// If the existing bundle is the same type, reuse it and update its properties
BNode::BComp(ref mut bcomp)
if self.type_id == bcomp.type_id && self.key == bcomp.key =>
{
bcomp
}
_ => {
let (node_ref, self_) = self.attach(parent_scope, parent, next_sibling);
ancestor.replace(parent, self_.into());
bundle.replace(parent, self_.into());
return node_ref;
}
};
Expand Down Expand Up @@ -239,16 +239,16 @@ mod tests {
let parent_scope: AnyScope = AnyScope::test();
let parent_element = document.create_element("div").unwrap();

let ancestor = html! { <Comp></Comp> };
let (_, mut comp) = ancestor.attach(&parent_scope, &parent_element, NodeRef::default());
let comp = html! { <Comp></Comp> };
let (_, mut bundle) = comp.attach(&parent_scope, &parent_element, NodeRef::default());

for _ in 0..10000 {
let node = html! { <Comp></Comp> };
node.reconcile(
&parent_scope,
&parent_element,
NodeRef::default(),
&mut comp,
&mut bundle,
);
}
}
Expand Down
16 changes: 9 additions & 7 deletions packages/yew/src/dom_bundle/blist.rs
Expand Up @@ -53,16 +53,16 @@ impl<'s> ElementWriter<'s> {
)
}

fn patch(self, node: VNode, ancestor: &mut BNode) -> Self {
test_log!("patching: {:?} -> {:?}", ancestor, node);
fn patch(self, node: VNode, bundle: &mut BNode) -> Self {
test_log!("patching: {:?} -> {:?}", bundle, node);
test_log!(
" parent={:?}, next_sibling={:?}",
self.parent.outer_html(),
self.next_sibling
);
// Advance the next sibling reference (from right to left)
ancestor.shift(self.parent, self.next_sibling.clone());
let next = node.reconcile(self.parent_scope, self.parent, self.next_sibling, ancestor);
bundle.shift(self.parent, self.next_sibling.clone());
let next = node.reconcile(self.parent_scope, self.parent, self.next_sibling, bundle);
test_log!(" next_position: {:?}", next);
Self {
next_sibling: next,
Expand Down Expand Up @@ -306,15 +306,15 @@ impl Reconcilable for VList {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
// Here, we will try to diff the previous list elements with the new
// ones we want to insert. For that, we will use two lists:
// - lefts: new elements to render in the DOM
// - rights: previously rendered elements.
//
// The left items are known since we want to insert them
// (self.children). For the right ones, we will look at the ancestor,
// (self.children). For the right ones, we will look at the bundle,
// i.e. the current DOM list element that we want to replace with self.

if self.children.is_empty() {
Expand All @@ -325,7 +325,9 @@ impl Reconcilable for VList {
}

let lefts = self.children;
let blist = ancestor.make_list();
// 'Forcefully' create a pretend the existing node is a list. Creates a
// singleton list if it isn't already.
let blist = bundle.make_list();
let rights = &mut blist.rev_children;
test_log!("lefts: {:?}", lefts);
test_log!("rights: {:?}", rights);
Expand Down
31 changes: 16 additions & 15 deletions packages/yew/src/dom_bundle/bnode.rs
Expand Up @@ -133,29 +133,30 @@ impl Reconcilable for VNode {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
match self {
VNode::VTag(vtag) => vtag.reconcile(parent_scope, parent, next_sibling, ancestor),
VNode::VText(vtext) => vtext.reconcile(parent_scope, parent, next_sibling, ancestor),
VNode::VComp(vcomp) => vcomp.reconcile(parent_scope, parent, next_sibling, ancestor),
VNode::VList(vlist) => vlist.reconcile(parent_scope, parent, next_sibling, ancestor),
VNode::VTag(vtag) => vtag.reconcile(parent_scope, parent, next_sibling, bundle),
VNode::VText(vtext) => vtext.reconcile(parent_scope, parent, next_sibling, bundle),
VNode::VComp(vcomp) => vcomp.reconcile(parent_scope, parent, next_sibling, bundle),
VNode::VList(vlist) => vlist.reconcile(parent_scope, parent, next_sibling, bundle),
VNode::VRef(node) => {
if let BNode::BRef(ref n) = ancestor {
if &node == n {
return NodeRef::new(node);
let _existing = match bundle {
BNode::BRef(ref n) if &node == n => n,
_ => {
let (node_ref, self_) =
VNode::VRef(node).attach(parent_scope, parent, next_sibling);
bundle.replace(parent, self_);
return node_ref;
}
}
let (node_ref, self_) =
VNode::VRef(node).attach(parent_scope, parent, next_sibling);
ancestor.replace(parent, self_);
node_ref
};
NodeRef::new(node)
}
VNode::VPortal(vportal) => {
vportal.reconcile(parent_scope, parent, next_sibling, ancestor)
vportal.reconcile(parent_scope, parent, next_sibling, bundle)
}
VNode::VSuspense(vsuspsense) => {
vsuspsense.reconcile(parent_scope, parent, next_sibling, ancestor)
vsuspsense.reconcile(parent_scope, parent, next_sibling, bundle)
}
}
}
Expand Down
51 changes: 29 additions & 22 deletions packages/yew/src/dom_bundle/bportal.rs
Expand Up @@ -6,7 +6,6 @@ use crate::dom_bundle::{DomBundle, Reconcilable};
use crate::html::{AnyScope, NodeRef};
use crate::virtual_dom::Key;
use crate::virtual_dom::VPortal;
use std::borrow::BorrowMut;
use web_sys::Element;

/// The bundle implementation to [VPortal].
Expand All @@ -15,7 +14,7 @@ pub struct BPortal {
/// The element under which the content is inserted.
host: Element,
/// The next sibling after the inserted content
next_sibling: NodeRef,
inner_sibling: NodeRef,
/// The inserted node
node: Box<BNode>,
}
Expand All @@ -41,18 +40,18 @@ impl Reconcilable for VPortal {
_parent: &Element,
host_next_sibling: NodeRef,
) -> (NodeRef, Self::Bundle) {
let VPortal {
let Self {
host,
next_sibling,
inner_sibling,
node,
} = self;
let (_, inner) = node.attach(parent_scope, &host, next_sibling.clone());
let (_, inner) = node.attach(parent_scope, &host, inner_sibling.clone());
(
host_next_sibling,
BPortal {
host,
node: Box::new(inner),
next_sibling,
inner_sibling,
},
)
}
Expand All @@ -62,25 +61,33 @@ impl Reconcilable for VPortal {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
if let BNode::BPortal(portal) = ancestor {
let old_host = std::mem::replace(&mut portal.host, self.host);
let old_sibling = std::mem::replace(&mut portal.next_sibling, self.next_sibling);
let node = &mut portal.node;
if old_host != portal.host || old_sibling != portal.next_sibling {
// Remount the inner node somewhere else instead of diffing
// Move the node, but keep the state
node.shift(&portal.host, portal.next_sibling.clone());
let portal = match bundle {
BNode::BPortal(portal) => portal,
_ => {
let (self_ref, self_) = self.attach(parent_scope, parent, next_sibling);
bundle.replace(parent, self_.into());
return self_ref;
}
let inner_ancestor = node.borrow_mut();
self.node
.reconcile(parent_scope, parent, next_sibling.clone(), inner_ancestor);
return next_sibling;
}
};
let Self {
host,
inner_sibling,
node,
} = self;

let old_host = std::mem::replace(&mut portal.host, host);
let old_inner_sibling = std::mem::replace(&mut portal.inner_sibling, inner_sibling);

let (_, self_) = self.attach(parent_scope, parent, next_sibling.clone());
ancestor.replace(parent, self_.into());
if old_host != portal.host || old_inner_sibling != portal.inner_sibling {
// Remount the inner node somewhere else instead of diffing
// Move the node, but keep the state
portal
.node
.shift(&portal.host, portal.inner_sibling.clone());
}
node.reconcile(parent_scope, parent, next_sibling.clone(), &mut portal.node);
next_sibling
}
}
Expand Down
24 changes: 12 additions & 12 deletions packages/yew/src/dom_bundle/bsuspense.rs
Expand Up @@ -90,9 +90,9 @@ impl Reconcilable for VSuspense {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
let suspense = match ancestor {
let suspense = match bundle {
// We only preserve the child state if they are the same suspense.
BNode::BSuspense(m)
if m.key == self.key && self.detached_parent == m.detached_parent =>
Expand All @@ -101,41 +101,41 @@ impl Reconcilable for VSuspense {
}
_ => {
let (self_ref, self_) = self.attach(parent_scope, parent, next_sibling);
ancestor.replace(parent, self_.into());
bundle.replace(parent, self_.into());
return self_ref;
}
};
let children_ancestor = &mut suspense.children;
let children_bundle = &mut suspense.children;
// no need to update key & detached_parent

// When it's suspended, we render children into an element that is detached from the dom
// tree while rendering fallback UI into the original place where children resides in.
match (self.suspended, &mut suspense.fallback) {
(true, Some(fallback_ancestor)) => {
(true, Some(fallback_bundle)) => {
self.children.reconcile(
parent_scope,
&self.detached_parent,
NodeRef::default(),
children_ancestor,
children_bundle,
);

self.fallback
.reconcile(parent_scope, parent, next_sibling, fallback_ancestor)
.reconcile(parent_scope, parent, next_sibling, fallback_bundle)
}

(false, None) => {
self.children
.reconcile(parent_scope, parent, next_sibling, children_ancestor)
.reconcile(parent_scope, parent, next_sibling, children_bundle)
}

(true, None) => {
children_ancestor.shift(&self.detached_parent, NodeRef::default());
children_bundle.shift(&self.detached_parent, NodeRef::default());

self.children.reconcile(
parent_scope,
&self.detached_parent,
NodeRef::default(),
children_ancestor,
children_bundle,
);
// first render of fallback
let (fallback_ref, fallback) =
Expand All @@ -147,9 +147,9 @@ impl Reconcilable for VSuspense {
(false, Some(_)) => {
suspense.fallback.take().unwrap().detach(parent);

children_ancestor.shift(parent, next_sibling.clone());
children_bundle.shift(parent, next_sibling.clone());
self.children
.reconcile(parent_scope, parent, next_sibling, children_ancestor)
.reconcile(parent_scope, parent, next_sibling, children_bundle)
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions packages/yew/src/dom_bundle/btag.rs
Expand Up @@ -136,12 +136,12 @@ impl Reconcilable for VTag {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
node_bundle: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
// This kind of branching patching routine reduces branch predictor misses and the need to
// unpack the enums (including `Option`s) all the time, resulting in a more streamlined
// patching flow
let is_matching_tag = match node_bundle {
let is_matching_tag = match bundle {
BNode::BTag(ex) if self.key == ex.key => match (&self.inner, &ex.inner) {
(VTagInner::Input(_), BTagInner::Input(_)) => true,
(VTagInner::Textarea { .. }, BTagInner::Textarea { .. }) => true,
Expand All @@ -155,7 +155,7 @@ impl Reconcilable for VTag {
// If the ancestor is a tag of the same type, don't recreate, keep the
// old tag and update its attributes and children.
let tag = if is_matching_tag {
match node_bundle {
match bundle {
BNode::BTag(a) => {
// Preserve the reference that already exists
a.deref_mut()
Expand All @@ -164,7 +164,7 @@ impl Reconcilable for VTag {
}
} else {
let (self_ref, self_) = self.attach(parent_scope, parent, next_sibling);
node_bundle.replace(parent, self_.into());
bundle.replace(parent, self_.into());
return self_ref;
};

Expand Down
10 changes: 5 additions & 5 deletions packages/yew/src/dom_bundle/btext.rs
Expand Up @@ -55,14 +55,14 @@ impl Reconcilable for VText {
parent_scope: &AnyScope,
parent: &Element,
next_sibling: NodeRef,
ancestor: &mut BNode,
bundle: &mut BNode,
) -> NodeRef {
let btext = match ancestor {
let btext = match bundle {
BNode::BText(btext) => btext,
_ => {
let (node_ref, self_) = self.attach(parent_scope, parent, next_sibling);
ancestor.replace(parent, self_.into());
return node_ref;
let (self_ref, self_) = self.attach(parent_scope, parent, next_sibling);
bundle.replace(parent, self_.into());
return self_ref;
}
};
let Self { text } = self;
Expand Down

0 comments on commit bcde660

Please sign in to comment.