Keep the outline intact when move_bookmark gets an invalid target (#4901)

This commit is contained in:
NetterSilver authored and GitHub committed 2026-11-09 10:09:46 +08:00
1 parent 98b4761934
commit ebcc564f1e
2 files changed
+11 -1

No files matched your search

+2 -1
View File
@@ -700,6 +700,8 @@ pub fn move_bookmark(doc: &mut Document, from: &[usize], to_parent: &[usize], in
return Err(OutlineError::IntoItself);
}
let (r, old_parent) = resolve_path(doc, from)?;
// Validate the target before touching the old parent, so an error leaves the outline intact.
let parent = container(doc, to_parent)?;
let mut old = children_of(doc, old_parent, &mut HashSet::from([old_parent]));
old.retain(|k| *k != r);
relink(doc, old_parent, &old)?;
@@ -709,7 +711,6 @@ pub fn move_bookmark(doc: &mut Document, from: &[usize], to_parent: &[usize], in
if to_parent.len() > depth && to_parent[..depth] == from[..depth] && to_parent[depth] > from[depth] {
to_parent[depth] -= 1;
}
let parent = container(doc, &to_parent)?;
let mut kids = children_of(doc, parent, &mut HashSet::from([parent]));
let at = index.min(kids.len());
kids.insert(at, r);
+9
View File
@@ -1731,6 +1731,15 @@ fn count_of(doc: &Document, r: ObjRef) -> Option<i64> {
doc.get(r).as_dict().and_then(|d| d.int(b"Count"))
}
#[test]
fn move_bookmark_to_missing_parent_keeps_outline() {
let mut d = doc_a();
crate::add_bookmark(&mut d, &[], 0, "Intro", 0).unwrap();
crate::add_bookmark(&mut d, &[], 9, "Results", 2).unwrap();
assert!(crate::move_bookmark(&mut d, &[0], &[7], 0).is_err());
assert_eq!(titles(&crate::bookmarks(&d)), ["Intro", "Results"]);
}
#[test]
fn bookmarks_add_rename_move_delete() {
let mut d = doc_a();