Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
81329ff
Cargo.lock
mobile-bungalow Oct 30, 2024
9c5c451
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Nov 6, 2024
b564457
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Nov 14, 2024
2910034
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Nov 22, 2024
58d6026
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Nov 25, 2024
2663b51
Merge branch 'main' of https://github.com/liveview-native/liveview-na…
mobile-bungalow Nov 26, 2024
5376d18
bump to main
mobile-bungalow Dec 2, 2024
8d2f839
merge
mobile-bungalow Dec 2, 2024
f5d881c
merge diff now ends when teh channel shuts down
mobile-bungalow Dec 2, 2024
1dd96c5
event tags
mobile-bungalow Dec 3, 2024
a0f628c
initial nop locking
mobile-bungalow Dec 4, 2024
0941c3a
remove cruft
mobile-bungalow Dec 4, 2024
1e391b2
remove cruft
mobile-bungalow Dec 4, 2024
ec279ca
simple locking
mobile-bungalow Dec 4, 2024
fe5714b
loosely couple phx event logic in case we need to dynamic dispatch in…
mobile-bungalow Dec 4, 2024
372dec1
even sending pretest
mobile-bungalow Dec 5, 2024
44d496a
added test
mobile-bungalow Dec 5, 2024
db50cd1
test initially passing
mobile-bungalow Dec 6, 2024
1934458
clippy
mobile-bungalow Dec 6, 2024
c7919a6
clippy
mobile-bungalow Dec 6, 2024
c5e9d0a
clippy
mobile-bungalow Dec 6, 2024
6e54a30
click test passing
mobile-bungalow Dec 6, 2024
abacdcf
more resilient event desierialization
mobile-bungalow Dec 6, 2024
351b45a
basic click passing
mobile-bungalow Dec 6, 2024
4bf03b9
clippy
mobile-bungalow Dec 6, 2024
6bb7d0c
tokio
mobile-bungalow Dec 7, 2024
6fe6932
failing test: we should propogate events to the change handler
mobile-bungalow Dec 8, 2024
654c8a3
placeholder: failing test because the dom does not have mutation list…
mobile-bungalow Dec 10, 2024
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 9 additions & 14 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,12 @@ publish.workspace = true


[lib]
crate-type = [
"staticlib",
"rlib",
"cdylib"
]
crate-type = ["staticlib", "rlib", "cdylib"]
name = "liveview_native_core"

[features]
default = ["liveview-channels-tls"]
liveview-channels = [
"phoenix_channels_client",
"reqwest",
"uniffi/tokio",
]
liveview-channels = ["phoenix_channels_client", "reqwest", "uniffi/tokio"]
liveview-channels-tls = [
"liveview-channels",
"reqwest/native-tls-vendored",
Expand All @@ -38,18 +30,21 @@ liveview-channels-tls = [

# This is for support of phoenix-channnels-client in for wasm.
browser = [
#"liveview-channels",
#"phoenix_channels_client/browser",
#"liveview-channels",
#"phoenix_channels_client/browser",
]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
futures = "0.3.31"
cranelift-entity = { version = "0.114" }
fixedbitset = { version = "0.4" }
fxhash = { version = "0.2" }
html5gum = { git = "https://github.com/liveviewnative/html5gum", branch = "lvn" }
petgraph = { version = "0.6", default-features = false, features = ["graphmap"] }
petgraph = { version = "0.6", default-features = false, features = [
"graphmap",
] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
smallstr = { version = "0.3", features = ["union"] }
Expand All @@ -69,7 +64,7 @@ Inflector = "0.11"
paste = { version = "1.0" }
pretty_assertions = { version = "1.4.0" }
text-diff = { version = "0.4.0" }
uniffi = { workspace = true, features = ["bindgen-tests", "tokio"]}
uniffi = { workspace = true, features = ["bindgen-tests", "tokio"] }
tokio = { version = "1.42", features = ["full"] }
env_logger = "0.11.1"

Expand Down
160 changes: 116 additions & 44 deletions crates/core/src/diff/patch.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::traversal::MoveTo;
use crate::dom::*;
use crate::live_socket::dom_locking::*;

#[derive(Debug, PartialEq, Clone)]
pub enum Patch {
Expand Down Expand Up @@ -125,20 +126,31 @@ impl Patch {
{
match self {
Self::InsertBefore { before, node: data } => {
let node = doc.insert_before(data.clone(), before);
let parent = doc
.document()
.parent(node)
.expect("inserted node should have parent");
Some(PatchResult::Add { node, parent, data })
let d = doc.document();
let parent = d.parent(before).expect("inserted node should have parent");
let speculative = BeforePatch::Add { parent };

if doc.document().can_complete_change(&speculative) {
let node = doc.insert_before(data.clone(), before);
Some(PatchResult::Add { node, parent, data })
} else {
None
}
}
Self::InsertAfter { after, node: data } => {
let node = doc.insert_after(data.clone(), after);
let parent = doc
.document()
.parent(node)
.parent(after)
.expect("inserted node should have parent");
Some(PatchResult::Add { node, parent, data })

let speculative = BeforePatch::Add { parent };

if doc.document().can_complete_change(&speculative) {
let node = doc.insert_after(data.clone(), after);
Some(PatchResult::Add { node, parent, data })
} else {
None
}
}
Self::Create { node } => {
let node = doc.push_node(node);
Expand Down Expand Up @@ -183,11 +195,18 @@ impl Patch {
}
Self::PrependBefore { before } => {
let node = stack.pop().unwrap();

let d = doc.document_mut();
d.insert_before(node, before);
let parent = d.parent(before).expect("inserted node should have parent");
let data = d.get(node).clone();
Some(PatchResult::Add { node, parent, data })
let speculative = BeforePatch::Add { parent };

if d.can_complete_change(&speculative) {
d.insert_before(node, before);
let data = d.get(node).clone();
Some(PatchResult::Add { node, parent, data })
} else {
None
}
}
Self::Append { node: data } => {
let node = doc.append(data.clone());
Expand All @@ -198,62 +217,115 @@ impl Patch {
})
}
Self::AppendTo { parent, node: data } => {
let node = doc.append_child(parent, data.clone());
Some(PatchResult::Add { node, parent, data })
let speculative = BeforePatch::Add { parent };

if doc.document().can_complete_change(&speculative) {
let node = doc.append_child(parent, data.clone());
Some(PatchResult::Add { node, parent, data })
} else {
None
}
}
Self::AppendAfter { after } => {
let node = stack.pop().unwrap();
let d = doc.document_mut();
d.insert_after(node, after);
let parent = d.parent(after).expect("inserted node should have parent");
let data = d.get(node).clone();
Some(PatchResult::Add { node, parent, data })

let speculative = BeforePatch::Add { parent };

if d.can_complete_change(&speculative) {
let node = stack.pop().unwrap();
d.insert_after(node, after);
let data = d.get(node).clone();
Some(PatchResult::Add { node, parent, data })
} else {
None
}
}
Self::Remove { node } => {
let data = doc.document().get(node).clone();
let parent = doc.document_mut().parent(node);
doc.remove(node);
parent.map(|parent| PatchResult::Remove { node, parent, data })

let speculative = BeforePatch::Remove { node };
if doc.document().can_complete_change(&speculative) {
doc.remove(node);
parent.map(|parent| PatchResult::Remove { node, parent, data })
} else {
None
}
}
Self::Replace { node, replacement } => {
let data = doc.document().get(node).clone();
let parent = doc.document_mut().parent(node)?;
doc.replace(node, replacement);
Some(PatchResult::Replace { node, parent, data })

let speculative = BeforePatch::Replace { node };

if doc.document().can_complete_change(&speculative) {
doc.replace(node, replacement);
Some(PatchResult::Replace { node, parent, data })
} else {
None
}
}
Self::AddAttribute { name, value } => {
doc.set_attribute(name, value);
let node = doc.insertion_point();
let data = doc.document().get(node).clone();
Some(PatchResult::Change { node, data })

let speculative = BeforePatch::Change { node };

if doc.document().can_complete_change(&speculative) {
let data = doc.document().get(node).clone();
Some(PatchResult::Change { node, data })
} else {
None
}
}
Self::AddAttributeTo { node, name, value } => {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.set_attribute(name, value);
Some(PatchResult::Change { node, data })
let speculative = BeforePatch::Change { node };
if doc.document().can_complete_change(&speculative) {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.set_attribute(name, value);
Some(PatchResult::Change { node, data })
} else {
None
}
}
Self::UpdateAttribute { node, name, value } => {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.set_attribute(name, value);
Some(PatchResult::Change { node, data })
let speculative = BeforePatch::Change { node };
if doc.document().can_complete_change(&speculative) {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.set_attribute(name, value);
Some(PatchResult::Change { node, data })
} else {
None
}
}
Self::RemoveAttributeByName { node, name } => {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.remove_attribute(name);
Some(PatchResult::Change { node, data })
let speculative = BeforePatch::Change { node };
if doc.document().can_complete_change(&speculative) {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.remove_attribute(name);
Some(PatchResult::Change { node, data })
} else {
None
}
}
Self::SetAttributes { node, attributes } => {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.replace_attributes(attributes);
Some(PatchResult::Change { node, data })
let speculative = BeforePatch::Change { node };
if doc.document().can_complete_change(&speculative) {
let data = doc.document().get(node).clone();
let mut guard = doc.insert_guard();
guard.set_insertion_point(node);
guard.replace_attributes(attributes);
Some(PatchResult::Change { node, data })
} else {
None
}
}
Self::Move(MoveTo::Node(node)) => {
doc.set_insertion_point(node);
Expand Down
24 changes: 24 additions & 0 deletions crates/core/src/dom/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,36 @@ use smallstr::SmallString;

use crate::InternedString;

#[macro_export]
macro_rules! attr {
($name:literal) => {
Attribute::new($name, None)
};
($name:literal= $value:expr) => {
Attribute::new($name, Some($value.to_string()))
};
($namespace:literal : $name:literal) => {
Attribute {
name: AttributeName::new_with_namespace($namespace, $name),
value: None,
}
};
($namespace:literal : $name:literal = $value:expr) => {
Attribute {
name: AttributeName::new_with_namespace($namespace, $name),
value: Some($value.to_string()),
}
};
}

Comment on lines +7 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this moment, I think this macro is only used in tests so it should probably go behind a #[cfg(test)] or in a test module.

/// Represents the fully-qualified name of an attribute
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, uniffi::Record)]
pub struct AttributeName {
/// This is used by svg attributes, e.g. `xlink-href`
pub namespace: Option<String>,
pub name: String,
}

impl fmt::Display for AttributeName {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(ref ns) = self.namespace {
Expand Down Expand Up @@ -62,6 +85,7 @@ pub struct Attribute {
pub name: AttributeName,
pub value: Option<String>,
}

impl Attribute {
/// Creates a new attribute with the given name and value
///
Expand Down
Loading
Loading