chore: get event test working
This commit is contained in:
1 parent
565df11f7b
commit
0027cdd938
5 files changed
+263
-214
No files matched your search
@@ -6,17 +6,23 @@ pub struct ElementId(pub usize);
|
||||
|
||||
pub struct ElementRef {
|
||||
// the pathway of the real element inside the template
|
||||
pub path: &'static [u8],
|
||||
pub path: ElementPath,
|
||||
|
||||
// The actual template
|
||||
pub template: *mut VNode<'static>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum ElementPath {
|
||||
Deep(&'static [u8]),
|
||||
Root(usize),
|
||||
}
|
||||
|
||||
impl ElementRef {
|
||||
pub fn null() -> Self {
|
||||
Self {
|
||||
template: std::ptr::null_mut(),
|
||||
path: &[],
|
||||
path: ElementPath::Root(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +34,21 @@ impl<'b> VirtualDom {
|
||||
|
||||
entry.insert(ElementRef {
|
||||
template: template as *const _ as *mut _,
|
||||
path,
|
||||
path: ElementPath::Deep(path),
|
||||
});
|
||||
|
||||
println!("Claiming {}", id);
|
||||
|
||||
ElementId(id)
|
||||
}
|
||||
|
||||
pub fn next_root(&mut self, template: &VNode, path: usize) -> ElementId {
|
||||
let entry = self.elements.vacant_entry();
|
||||
let id = entry.key();
|
||||
|
||||
entry.insert(ElementRef {
|
||||
template: template as *const _ as *mut _,
|
||||
path: ElementPath::Root(path),
|
||||
});
|
||||
|
||||
println!("Claiming {}", id);
|
||||
@@ -76,3 +96,30 @@ impl<'b> VirtualDom {
|
||||
// }
|
||||
}
|
||||
}
|
||||
impl ElementPath {
|
||||
pub(crate) fn is_ascendant(&self, big: &&[u8]) -> bool {
|
||||
match *self {
|
||||
ElementPath::Deep(small) => small.len() <= big.len() && small == &big[..small.len()],
|
||||
ElementPath::Root(r) => big.len() == 1 && big[0] == r as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn path_ascendant() {
|
||||
// assert!(&ElementPath::Deep(&[]).is_ascendant(&&[0_u8]));
|
||||
// assert!(&ElementPath::Deep(&[1, 2]), &[1, 2, 3]);
|
||||
// assert!(!is_path_ascendant(
|
||||
// &ElementPath::Deep(&[1, 2, 3, 4]),
|
||||
// &[1, 2, 3]
|
||||
// ));
|
||||
}
|
||||
|
||||
impl PartialEq<&[u8]> for ElementPath {
|
||||
fn eq(&self, other: &&[u8]) -> bool {
|
||||
match *self {
|
||||
ElementPath::Deep(deep) => deep.eq(*other),
|
||||
ElementPath::Root(r) => other.len() == 1 && other[0] == r as u8,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,8 @@ impl<'b: 'static> VirtualDom {
|
||||
}
|
||||
|
||||
TemplateNode::Element { .. } | TemplateNode::Text(_) => {
|
||||
let this_id = self.next_element(template, &[]);
|
||||
let this_id = self.next_root(template, root_idx);
|
||||
|
||||
template.root_ids[root_idx].set(this_id);
|
||||
self.mutations.push(LoadTemplate {
|
||||
name: template.template.id,
|
||||
|
||||
@@ -6,7 +6,7 @@ use crate::{
|
||||
any_props::VProps,
|
||||
arena::{ElementId, ElementRef},
|
||||
factory::RenderReturn,
|
||||
innerlude::{DirtyScope, Mutations, Scheduler, SchedulerMsg},
|
||||
innerlude::{DirtyScope, ElementPath, Mutations, Scheduler, SchedulerMsg},
|
||||
mutations::Mutation,
|
||||
nodes::{Template, TemplateId},
|
||||
scheduler::{SuspenseBoundary, SuspenseId},
|
||||
@@ -368,15 +368,11 @@ impl VirtualDom {
|
||||
let target_path = el_ref.path;
|
||||
|
||||
for (idx, attr) in template.dynamic_attrs.iter().enumerate() {
|
||||
fn is_path_ascendant(small: &[u8], big: &[u8]) -> bool {
|
||||
small.len() >= big.len() && small == &big[..small.len()]
|
||||
}
|
||||
|
||||
let this_path = template.template.attr_paths[idx];
|
||||
|
||||
// listeners are required to be prefixed with "on", but they come back to the virtualdom with that missing
|
||||
// we should fix this so that we look for "onclick" instead of "click"
|
||||
if &attr.name[2..] == name && is_path_ascendant(&target_path, &this_path) {
|
||||
if &attr.name[2..] == name && target_path.is_ascendant(&this_path) {
|
||||
listeners.push(&attr.value);
|
||||
|
||||
// Break if the event doesn't bubble anyways
|
||||
@@ -387,7 +383,7 @@ impl VirtualDom {
|
||||
// Break if this is the exact target element.
|
||||
// This means we won't call two listeners with the same name on the same element. This should be
|
||||
// documented, or be rejected from the rsx! macro outright
|
||||
if this_path == target_path {
|
||||
if target_path == this_path {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user