From aff2de64c7f950b0e204e4c3e7e094e644847f4d Mon Sep 17 00:00:00 2001 From: clover caruso Date: Sat, 3 Oct 2026 22:26:54 -0700 Subject: [PATCH] fix: restore the whole outline after cutting its only picture Keep the empty text paragraph when reconstructing an emptied outline for Undo. Cover Cut, Undo, Redo, and Undo on a lone inline picture. Refs #80 Assisted-by: gpt-6.1-sol --- crates/canvas/src/editor.rs | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/crates/canvas/src/editor.rs b/crates/canvas/src/editor.rs index 32a0a418f5b07af5fe891799ac6d889274ef842e..bbb5bee4dd3388c51b064fdb71c50803aebe0e55 100644 --- a/crates/canvas/src/editor.rs +++ b/crates/canvas/src/editor.rs @@ -4855,9 +4855,10 @@ impl CanvasEditor { }; let outline = self.outlines.remove(index); self.record(Ok(vec![PageOp::Delete { object: outline.id }])); - debug_assert_eq!(change.edit.range, 0..1); let mut source = outline.snapshot(); - source.paragraphs = change.edit.replacement; + source + .paragraphs + .splice(change.edit.range, change.edit.replacement); self.undo.push(History::Restore { index, source: Box::new(source), @@ -6496,6 +6497,33 @@ mod tests { } } + #[test] + fn cutting_the_only_picture_restores_its_empty_text_paragraph_on_undo() { + let mut engine = TextEngine::default(); + let document = + TextDocument::new(vec![Paragraph::new(String::new(), Format::default())]).unwrap(); + let mut editor = CanvasEditor::new(&mut engine, document, 240.0).unwrap(); + editor + .create_outline(&mut engine, [36.0, 36.0], 240.0) + .unwrap(); + let image = picture( + include_bytes!("../../../corpus/object-tags/native/notebook/photo.png").to_vec(), + [40.0, 30.0], + ) + .unwrap(); + let id = image.id; + editor.insert_picture(&mut engine, image).unwrap(); + editor.remove_image(&mut engine, id).unwrap(); + assert!(editor.active_outline().is_empty()); + assert!(editor.undo(&mut engine).unwrap()); + assert!(editor.image_placement(id).is_some()); + assert_eq!(editor.active_outline().document.nodes().len(), 2); + assert!(editor.redo(&mut engine).unwrap()); + assert!(editor.active_outline().is_empty()); + assert!(editor.undo(&mut engine).unwrap()); + assert!(editor.image_placement(id).is_some()); + } + #[test] fn pictures_move_and_resize_through_history_and_backgrounds_stay_put() { use onestore::page::{Image, Page, PageObject}; -- 2.54.0