fn apply(
        &mut self,
        parent_scope: &AnyScope,
        parent: &Element,
        next_sibling: NodeRef,
        ancestor: Option<VNode>,
    ) -> 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 (ancestor_tag, el) = match ancestor {
            Some(mut ancestor) => {
                // If the ancestor is a tag of the same type, don't recreate, keep the
                // old tag and update its attributes and children.
                if match &ancestor {
                    VNode::VTag(a) => {
                        self.key == a.key
                            && match (&self.inner, &a.inner) {
                                (VTagInner::Input(_), VTagInner::Input(_))
                                | (VTagInner::Textarea { .. }, VTagInner::Textarea { .. }) => true,
                                (
                                    VTagInner::Other { tag: l, .. },
                                    VTagInner::Other { tag: r, .. },
                                ) => l == r,
                                _ => false,
                            }
                    }
                    _ => false,
                } {
                    match ancestor {
                        VNode::VTag(mut a) => {
                            // Preserve the reference that already exists
                            let el = a.reference.take().unwrap();
                            a.node_ref.set(None);
                            (Some(a), el)
                        }
                        _ => unsafe { unreachable_unchecked() },
                    }
                } else {
                    let el = self.create_element(parent);
                    super::insert_node(&el, parent, ancestor.first_node().as_ref());
                    ancestor.detach(parent);
                    (None, el)
                }
            }
            None => (None, {
                let el = self.create_element(parent);
                super::insert_node(&el, parent, next_sibling.get().as_ref());
                el
            }),
        };

        match ancestor_tag {
            None => {
                self.attributes.apply(&el);
                self.listeners.apply(&el);

                match &mut self.inner {
                    VTagInner::Input(f) => {
                        f.apply(el.unchecked_ref());
                    }
                    VTagInner::Textarea { value } => {
                        value.apply(el.unchecked_ref());
                    }
                    VTagInner::Other { children, .. } => {
                        if !children.is_empty() {
                            children.apply(parent_scope, &el, NodeRef::default(), None);
                        }
                    }
                }
            }
            Some(ancestor) => {
                self.attributes.apply_diff(&el, ancestor.attributes);
                self.listeners.apply_diff(&el, ancestor.listeners);

                match (&mut self.inner, ancestor.inner) {
                    (VTagInner::Input(new), VTagInner::Input(old)) => {
                        new.apply_diff(el.unchecked_ref(), old);
                    }
                    (VTagInner::Textarea { value: new }, VTagInner::Textarea { value: old }) => {
                        new.apply_diff(el.unchecked_ref(), old);
                    }
                    (
                        VTagInner::Other { children: new, .. },
                        VTagInner::Other {
                            children: mut old, ..
                        },
                    ) => {
                        if !new.is_empty() {
                            new.apply(parent_scope, &el, NodeRef::default(), Some(old.into()));
                        } else if !old.is_empty() {
                            old.detach(&el);
                        }
                    }
                    // Can not happen, because we checked for tag equability above
                    _ => unsafe { unreachable_unchecked() },
                }
            }
        };

        self.node_ref.set(Some(el.deref().clone()));
        self.reference = el.into();
        self.node_ref.clone()
    }
/// Renders virtual tag over DOM [Element], but it also compares this with an ancestor [VTag]
/// to compute what to patch in the actual DOM nodes.
Renders virtual tag over DOM [Element], but it also compares this with an ancestor [VTag]
to compute what to patch in the actual DOM nodes.
Renders virtual tag over DOM [ Element ] but it also compares this with an ancestor [ VTag ] to compute what to patch in the actual DOM nodes .
fn apply(
        &mut self,
        parent_scope: &AnyScope,
        parent: &Element,
        next_sibling: NodeRef,
        ancestor: Option<VNode>,
    ) -> 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 (ancestor_tag, el) = match ancestor {
            Some(mut ancestor) => {
                // If the ancestor is a tag of the same type, don't recreate, keep the
                // old tag and update its attributes and children.
                if match &ancestor {
                    VNode::VTag(a) => {
                        self.key == a.key
                            && match (&self.inner, &a.inner) {
                                (VTagInner::Input(_), VTagInner::Input(_))
                                | (VTagInner::Textarea { .. }, VTagInner::Textarea { .. }) => true,
                                (
                                    VTagInner::Other { tag: l, .. },
                                    VTagInner::Other { tag: r, .. },
                                ) => l == r,
                                _ => false,
                            }
                    }
                    _ => false,
                } {
                    match ancestor {
                        VNode::VTag(mut a) => {
                            // Preserve the reference that already exists
                            let el = a.reference.take().unwrap();
                            a.node_ref.set(None);
                            (Some(a), el)
                        }
                        _ => unsafe { unreachable_unchecked() },
                    }
                } else {
                    let el = self.create_element(parent);
                    super::insert_node(&el, parent, ancestor.first_node().as_ref());
                    ancestor.detach(parent);
                    (None, el)
                }
            }
            None => (None, {
                let el = self.create_element(parent);
                super::insert_node(&el, parent, next_sibling.get().as_ref());
                el
            }),
        };
        match ancestor_tag {
            None => {
                self.attributes.apply(&el);
                self.listeners.apply(&el);
                match &mut self.inner {
                    VTagInner::Input(f) => {
                        f.apply(el.unchecked_ref());
                    }
                    VTagInner::Textarea { value } => {
                        value.apply(el.unchecked_ref());
                    }
                    VTagInner::Other { children, .. } => {
                        if !children.is_empty() {
                            children.apply(parent_scope, &el, NodeRef::default(), None);
                        }
                    }
                }
            }
            Some(ancestor) => {
                self.attributes.apply_diff(&el, ancestor.attributes);
                self.listeners.apply_diff(&el, ancestor.listeners);
                match (&mut self.inner, ancestor.inner) {
                    (VTagInner::Input(new), VTagInner::Input(old)) => {
                        new.apply_diff(el.unchecked_ref(), old);
                    }
                    (VTagInner::Textarea { value: new }, VTagInner::Textarea { value: old }) => {
                        new.apply_diff(el.unchecked_ref(), old);
                    }
                    (
                        VTagInner::Other { children: new, .. },
                        VTagInner::Other {
                            children: mut old, ..
                        },
                    ) => {
                        if !new.is_empty() {
                            new.apply(parent_scope, &el, NodeRef::default(), Some(old.into()));
                        } else if !old.is_empty() {
                            old.detach(&el);
                        }
                    }
                    // Can not happen, because we checked for tag equability above
                    _ => unsafe { unreachable_unchecked() },
                }
            }
        };
        self.node_ref.set(Some(el.deref().clone()));
        self.reference = el.into();
        self.node_ref.clone()
    }
fn apply ( & mut self , parent_scope : & AnyScope , parent : & Element , next_sibling : NodeRef , ancestor : Option < VNode > , ) -> 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 ( ancestor_tag , el ) = match ancestor { Some ( mut ancestor ) => { // If the ancestor is a tag of the same type, don't recreate, keep the // old tag and update its attributes and children. if match & ancestor { VNode :: VTag ( a ) => { self . key == a . key && match ( & self . inner , & a . inner ) { ( VTagInner :: Input ( _ ) , VTagInner :: Input ( _ ) ) | ( VTagInner :: Textarea { .. } , VTagInner :: Textarea { .. } ) => true , ( VTagInner :: Other { tag : l , .. } , VTagInner :: Other { tag : r , .. } , ) => l == r , _ => false , } } _ => false , } { match ancestor { VNode :: VTag ( mut a ) => { // Preserve the reference that already exists let el = a . reference . take ( ) . unwrap ( ) ; a . node_ref . set ( None ) ; ( Some ( a ) , el ) } _ => unsafe { unreachable_unchecked ( ) } , } } else { let el = self . create_element ( parent ) ; super :: insert_node ( & el , parent , ancestor . first_node ( ) . as_ref ( ) ) ; ancestor . detach ( parent ) ; ( None , el ) } } None => ( None , { let el = self . create_element ( parent ) ; super :: insert_node ( & el , parent , next_sibling . get ( ) . as_ref ( ) ) ; el } ) , } ; match ancestor_tag { None => { self . attributes . apply ( & el ) ; self . listeners . apply ( & el ) ; match & mut self . inner { VTagInner :: Input ( f ) => { f . apply ( el . unchecked_ref ( ) ) ; } VTagInner :: Textarea { value } => { value . apply ( el . unchecked_ref ( ) ) ; } VTagInner :: Other { children , .. } => { if ! children . is_empty ( ) { children . apply ( parent_scope , & el , NodeRef :: default ( ) , None ) ; } } } } Some ( ancestor ) => { self . attributes . apply_diff ( & el , ancestor . attributes ) ; self . listeners . apply_diff ( & el , ancestor . listeners ) ; match ( & mut self . inner , ancestor . inner ) { ( VTagInner :: Input ( new ) , VTagInner :: Input ( old ) ) => { new . apply_diff ( el . unchecked_ref ( ) , old ) ; } ( VTagInner :: Textarea { value : new } , VTagInner :: Textarea { value : old } ) => { new . apply_diff ( el . unchecked_ref ( ) , old ) ; } ( VTagInner :: Other { children : new , .. } , VTagInner :: Other { children : mut old , .. } , ) => { if ! new . is_empty ( ) { new . apply ( parent_scope , & el , NodeRef :: default ( ) , Some ( old . into ( ) ) ) ; } else if ! old . is_empty ( ) { old . detach ( & el ) ; } } // Can not happen, because we checked for tag equability above _ => unsafe { unreachable_unchecked ( ) } , } } } ; self . node_ref . set ( Some ( el . deref ( ) . clone ( ) ) ) ; self . reference = el . into ( ) ; self . node_ref . clone ( ) }
Renders virtual tag over DOM [Element], but it also compares this with an ancestor [VTag]
to compute what to patch in the actual DOM nodes.
Renders virtual tag over DOM [ Element ] but it also compares this with an ancestor [ VTag ] to compute what to patch in the actual DOM nodes .
&mut self
parent_scope
&AnyScope
parent
&Element
next_sibling
NodeRef
ancestor
Option<VNode>
&mut self
parent_scope
&AnyScope
parent
&Element
next_sibling
NodeRef
ancestor
Option<VNode>