Skip to content

Commit

Permalink
Add utility to build the array of ancestor handles from a handle (#537)
Browse files Browse the repository at this point in the history
* Add utility to build the array of ancestor handles from a handle

* Update documentation & remove unnecessary property assignment
  • Loading branch information
aringenbach authored Jan 30, 2023
1 parent a40f502 commit f3d9b3f
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 29 deletions.
32 changes: 14 additions & 18 deletions crates/wysiwyg/src/composer_model/menu_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,22 @@ where
set.contains(&OrderedList) || set.contains(&UnorderedList)
}

let mut reversed_actions = HashSet::new();
let mut cur_handle = handle.clone();

while !cur_handle.is_root() {
let reversed_action = self.reversed_action_for_handle(&cur_handle);
if let Some(action) = reversed_action {
match action {
// If there is multiple list types in the hierarchy we
// only keep the deepest list type.
OrderedList | UnorderedList
if has_list_in(&reversed_actions) => {}
_ => {
reversed_actions.insert(action);
handle.with_ancestors().iter().rev().fold(
HashSet::new(),
|mut set, handle| {
if let Some(action) = self.reversed_action_for_handle(handle) {
match action {
// If there is multiple list types in the hierarchy we
// only keep the deepest list type.
OrderedList | UnorderedList if has_list_in(&set) => {}
_ => {
set.insert(action);
}
}
}
}
cur_handle = cur_handle.parent_handle();
}

reversed_actions
set
},
)
}

fn reversed_action_for_handle(
Expand Down
27 changes: 27 additions & 0 deletions crates/wysiwyg/src/dom/dom_handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ impl DomHandle {
new_path.splice(0..old.raw().len(), new.into_raw());
self.path = Some(new_path.clone());
}

/// Returns a vec containing all ancestors handles of the handle,
/// ordered from root to self (included). Panics if handle is unset.
pub fn with_ancestors(&self) -> Vec<DomHandle> {
self.raw().iter().fold(vec![DomHandle::root()], |mut v, i| {
let last = v.last().unwrap();
v.push(last.child_handle(*i));
v
})
}
}

#[cfg(test)]
Expand Down Expand Up @@ -268,4 +278,21 @@ mod test {
let new_parent = DomHandle::from_raw(vec![7, 8]);
handle.replace_ancestor(parent, new_parent);
}

#[test]
fn with_ancestors_returns_all_ancestors_and_self() {
let handle = DomHandle::from_raw(vec![0, 1, 2, 4, 5]);
assert_eq!(
handle.with_ancestors(),
vec![
DomHandle::root(),
DomHandle::from_raw(vec![0]),
DomHandle::from_raw(vec![0, 1]),
DomHandle::from_raw(vec![0, 1, 2]),
DomHandle::from_raw(vec![0, 1, 2, 4]),
DomHandle::from_raw(vec![0, 1, 2, 4, 5]),
]
);
assert_eq!(DomHandle::root().with_ancestors(), vec![DomHandle::root()]);
}
}
23 changes: 12 additions & 11 deletions crates/wysiwyg/src/dom/dom_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,17 +275,18 @@ where
&self,
child_handle: &DomHandle,
) -> Option<DomHandle> {
if let DomNode::Container(n) = self.lookup_node(child_handle) {
if n.is_list_item() {
return Some(child_handle.clone());
}
}

if child_handle.has_parent() {
self.find_ancestor_list_item_or_self(&child_handle.parent_handle())
} else {
None
}
child_handle
.with_ancestors()
.iter()
.rev()
.find(|handle| {
if let DomNode::Container(n) = self.lookup_node(handle) {
n.is_list_item()
} else {
false
}
})
.cloned()
}

/// Find the node based on its handle.
Expand Down

0 comments on commit f3d9b3f

Please sign in to comment.