mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 09:29:44 -06:00
Threaded text: a frame listed twice flows the story once
Reflow copied each listed frame's text into its thread's story, so a document that listed one frame several times in a thread, or in several threads, repeated that text in the story and wrote the grown story back for the next thread to copy again, growing the text with every repetition while the document opened. Reflow now keeps each frame at its first place in the thread list only.
This commit is contained in:
committed by
bflatastic
parent
d9e3df23b1
commit
a4aa1960cf
@@ -93,7 +93,12 @@ thread_local! {
|
||||
/// makes "changed" a pointer comparison). Deleted frames' text flows into the remaining ones; a
|
||||
/// frame that is now point type leaves its thread with the text it holds.
|
||||
pub(crate) fn reflow(before: &Document, doc: &mut Document) {
|
||||
let threads = std::mem::take(&mut doc.text_threads);
|
||||
// A frame is in one thread, once: a file that lists it again (in its thread or another) would
|
||||
// copy its text into the story each time, and write the grown story back for the next thread
|
||||
// to copy again. Only its first place counts.
|
||||
let mut seen = std::collections::HashSet::new();
|
||||
let threads: Vec<Vec<NodeId>> =
|
||||
std::mem::take(&mut doc.text_threads).into_iter().map(|t| t.into_iter().filter(|id| seen.insert(*id)).collect()).collect();
|
||||
let mut kept = vec![];
|
||||
for thread in threads {
|
||||
let changed = thread.iter().any(|id| match (before.node(*id), doc.node(*id)) {
|
||||
|
||||
@@ -40,6 +40,24 @@ fn thread_flows_reflows_on_edit_and_survives_delete() {
|
||||
assert_eq!(s.doc().unwrap().doc.text_threads.len(), 1);
|
||||
}
|
||||
|
||||
/// A file that lists a frame more than once, in its own thread or in another, flows the story
|
||||
/// through each frame once: repeated places would copy its text again and again.
|
||||
#[test]
|
||||
fn frames_listed_twice_flow_the_story_once() {
|
||||
let (mut s, a, b) = setup();
|
||||
s.execute("text.thread.create", &json!({})).unwrap();
|
||||
let mut d = (*s.doc().unwrap().doc).clone();
|
||||
let (fa, fb) = (NodeId(a), NodeId(b));
|
||||
d.text_threads = vec![vec![fa, fb, fa, fb, fa], vec![fb, fa], vec![fa, fb]];
|
||||
reflow(&Document::new(1.0, 1.0), &mut d);
|
||||
assert_eq!(d.text_threads, vec![vec![fa, fb]]);
|
||||
let plain = |id: NodeId| match &d.node(id).unwrap().kind {
|
||||
NodeKind::Text(t) => t.plain_text(),
|
||||
_ => panic!("not text"),
|
||||
};
|
||||
assert_eq!(format!("{}{}", plain(fa), plain(fb)), TEXT.repeat(4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn edits_copy_only_the_stories_of_threads_whose_frames_changed() {
|
||||
let (mut s, a, b) = setup();
|
||||
|
||||
Reference in New Issue
Block a user