Feat: wire up a very basic dom updater

This commit is contained in:
Jonathan Kelley committed 2021-02-14 23:39:46 -05:00
1 parent 4dfdf91236
commit c4e8d8bb31
18 files changed
+1967 -1105

No files matched your search

+1
View File
@@ -31,3 +31,4 @@ id-arena = "2.2.1"
thiserror = "1.0.23"
fxhash = "0.2.1"
longest-increasing-subsequence = "0.1.0"
# hashbrown = { version = "0.9.1", features = ["bumpalo"] }
+283 -1076
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+6 -2
View File
@@ -65,11 +65,13 @@
//! - dioxus-liveview (SSR + StringRenderer)
//!
pub mod changelist; // An "edit phase" described by transitions and edit operations
// pub mod changelist; // An "edit phase" described by transitions and edit operations
pub mod component; // Logic for extending FC
pub mod context; // Logic for providing hook + context functionality to user components
pub mod debug_renderer; // Test harness for validating that lifecycles and diffs work appropriately
pub mod diff; // The diffing algorithm that builds the ChangeList
pub mod diff;
pub mod patch; // The diffing algorithm that builds the ChangeList
// pub mod dodriodiff; // The diffing algorithm that builds the ChangeList
pub mod error; // Error type we expose to the renderers
pub mod events; // Manages the synthetic event API
pub mod hooks; // Built-in hooks
@@ -137,5 +139,7 @@ pub mod prelude {
pub use dioxus_core_macro::fc;
pub use dioxus_html_2::html;
pub use crate::diff::DiffMachine;
pub use crate::hooks::*;
}
+3 -3
View File
@@ -366,7 +366,7 @@ where
/// let my_div = div(&b).attr("id", "my-div").finish();
/// ```
#[inline]
pub fn attr(mut self, name: &'a str, value: &'a str) -> Self {
pub fn attr(mut self, name: &'static str, value: &'a str) -> Self {
self.attributes.push(Attribute { name, value });
self
}
@@ -398,7 +398,7 @@ where
/// .bool_attr("hidden", Math::random() >= 0.5)
/// .finish();
/// ```
pub fn bool_attr(mut self, name: &'a str, should_add: bool) -> Self {
pub fn bool_attr(mut self, name: &'static str, should_add: bool) -> Self {
if should_add {
self.attributes.push(Attribute { name, value: "" });
}
@@ -1049,7 +1049,7 @@ pub fn text<'a>(contents: &'a str) -> VNode<'a> {
///
/// let my_id_attr = attr("id", "my-id");
/// ```
pub fn attr<'a>(name: &'a str, value: &'a str) -> Attribute<'a> {
pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> {
Attribute { name, value }
}
+2 -2
View File
@@ -143,8 +143,8 @@ mod velement {
/// `href="https://example.com"`.
#[derive(Clone, Debug)]
pub struct Attribute<'a> {
pub(crate) name: &'a str,
pub(crate) value: &'a str,
pub name: &'static str,
pub value: &'a str,
}
impl<'a> Attribute<'a> {
+79
View File
@@ -0,0 +1,79 @@
use fxhash::FxHashMap;
use crate::innerlude::{VNode, VText};
/// A Patch encodes an operation that modifies a real DOM element.
///
/// To update the real DOM that a user sees you'll want to first diff your
/// old virtual dom and new virtual dom.
///
/// This diff operation will generate `Vec<Patch>` with zero or more patches that, when
/// applied to your real DOM, will make your real DOM look like your new virtual dom.
///
/// Each Patch has a u32 node index that helps us identify the real DOM node that it applies to.
///
/// Our old virtual dom's nodes are indexed depth first, as shown in this illustration
/// (0 being the root node, 1 being it's first child, 2 being it's first child's first child).
///
/// ```text
/// .─.
/// ( 0 )
/// `┬'
/// ┌────┴──────┐
/// │ │
/// ▼ ▼
/// .─. .─.
/// ( 1 ) ( 4 )
/// `┬' `─'
/// ┌────┴───┐ ├─────┬─────┐
/// │ │ │ │ │
/// ▼ ▼ ▼ ▼ ▼
/// .─. .─. .─. .─. .─.
/// ( 2 ) ( 3 ) ( 5 ) ( 6 ) ( 7 )
/// `─' `─' `─' `─' `─'
/// ```
///
/// The patching process is tested in a real browser in crates/virtual-dom-rs/tests/diff_patch.rs
pub enum Patch<'a> {
/// Append a vector of child nodes to a parent node id.
AppendChildren(NodeIdx, Vec<&'a VNode<'a>>),
/// For a `node_i32`, remove all children besides the first `len`
TruncateChildren(NodeIdx, usize),
/// Replace a node with another node. This typically happens when a node's tag changes.
/// ex: <div> becomes <span>
Replace(NodeIdx, &'a VNode<'a>),
/// Add attributes that the new node has that the old node does not
AddAttributes(NodeIdx, FxHashMap<&'a str, &'a str>),
/// Remove attributes that the old node had that the new node doesn't
RemoveAttributes(NodeIdx, Vec<&'a str>),
/// Change the text of a Text node.
ChangeText(NodeIdx, &'a VText<'a>),
}
type NodeIdx = usize;
impl<'a> Patch<'a> {
/// Every Patch is meant to be applied to a specific node within the DOM. Get the
/// index of the DOM node that this patch should apply to. DOM nodes are indexed
/// depth first with the root node in the tree having index 0.
pub fn node_idx(&self) -> usize {
match self {
Patch::AppendChildren(node_idx, _) => *node_idx,
Patch::TruncateChildren(node_idx, _) => *node_idx,
Patch::Replace(node_idx, _) => *node_idx,
Patch::AddAttributes(node_idx, _) => *node_idx,
Patch::RemoveAttributes(node_idx, _) => *node_idx,
Patch::ChangeText(node_idx, _) => *node_idx,
}
}
}
pub struct PatchList<'a> {
patches: Vec<Patch<'a>>,
}
+6 -4
View File
@@ -1,4 +1,5 @@
use crate::{changelist::EditList, nodes::VNode};
// use crate::{changelist::EditList, nodes::VNode};
use crate::nodes::VNode;
use crate::{events::EventTrigger, innerlude::*};
use any::Any;
use bumpalo::Bump;
@@ -121,7 +122,8 @@ impl VirtualDom {
///
///
/// ```
pub async fn progress_with_event(&mut self, evt: EventTrigger) -> Result<EditList<'_>> {
pub async fn progress_with_event(&mut self, evt: EventTrigger) -> Result<()> {
// pub async fn progress_with_event(&mut self, evt: EventTrigger) -> Result<EditList<'_>> {
let EventTrigger {
component_id,
listener_id,
@@ -156,8 +158,8 @@ impl VirtualDom {
process_event(&mut self.components, event)?;
}
todo!()
// Ok(())
// todo!()
Ok(())
}
pub async fn progress_completely(&mut self) -> Result<()> {