Skip to content

Commit 21e4a19

Browse files
authored
fix: apply multiple styles via text delta at the end "\n" char (#692)
1 parent d89b0d8 commit 21e4a19

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

crates/loro-internal/src/handler.rs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,7 +2140,12 @@ impl TextHandler {
21402140
delta: &[TextDelta],
21412141
) -> LoroResult<()> {
21422142
let mut index = 0;
2143-
let mut marks = Vec::new();
2143+
struct PendingMark {
2144+
start: usize,
2145+
end: usize,
2146+
attributes: FxHashMap<InternalString, LoroValue>,
2147+
}
2148+
let mut marks: Vec<PendingMark> = Vec::new();
21442149
for d in delta {
21452150
match d {
21462151
TextDelta::Insert { insert, attributes } => {
@@ -2153,10 +2158,15 @@ impl TextHandler {
21532158
PosType::Event,
21542159
)?;
21552160

2161+
let mut pending_mark = PendingMark {
2162+
start: index,
2163+
end,
2164+
attributes: FxHashMap::default(),
2165+
};
21562166
for (key, value) in override_styles {
2157-
marks.push((index, end, key, value));
2167+
pending_mark.attributes.insert(key, value);
21582168
}
2159-
2169+
marks.push(pending_mark);
21602170
index = end;
21612171
}
21622172
TextDelta::Delete { delete } => {
@@ -2166,9 +2176,17 @@ impl TextHandler {
21662176
let end = index + *retain;
21672177
match attributes {
21682178
Some(attr) if !attr.is_empty() => {
2179+
let mut pending_mark = PendingMark {
2180+
start: index,
2181+
end,
2182+
attributes: FxHashMap::default(),
2183+
};
21692184
for (key, value) in attr {
2170-
marks.push((index, end, key.deref().into(), value.clone()));
2185+
pending_mark
2186+
.attributes
2187+
.insert(key.deref().into(), value.clone());
21712188
}
2189+
marks.push(pending_mark);
21722190
}
21732191
_ => {}
21742192
}
@@ -2178,13 +2196,22 @@ impl TextHandler {
21782196
}
21792197

21802198
let mut len = self.len_event();
2181-
for (start, end, key, value) in marks {
2182-
if start >= len {
2183-
self.insert_with_txn(txn, len, &"\n".repeat(start - len + 1))?;
2184-
len = start;
2199+
for pending_mark in marks {
2200+
if pending_mark.start >= len {
2201+
self.insert_with_txn(txn, len, &"\n".repeat(pending_mark.start - len + 1))?;
2202+
len = pending_mark.start;
21852203
}
21862204

2187-
self.mark_with_txn(txn, start, end, key.deref(), value, false)?;
2205+
for (key, value) in pending_mark.attributes {
2206+
self.mark_with_txn(
2207+
txn,
2208+
pending_mark.start,
2209+
pending_mark.end,
2210+
key.deref(),
2211+
value,
2212+
false,
2213+
)?;
2214+
}
21882215
}
21892216

21902217
Ok(())

crates/loro/tests/loro_rust_test.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3275,3 +3275,34 @@ fn test_to_delta_on_detached_text() {
32753275
}]
32763276
);
32773277
}
3278+
3279+
#[test]
3280+
fn test_apply_delta_on_the_end() {
3281+
let doc = LoroDoc::new();
3282+
doc.get_text("text").insert(0, "Hello").unwrap();
3283+
doc.get_text("text").apply_delta(&[
3284+
TextDelta::Retain {
3285+
retain: 5,
3286+
attributes: None,
3287+
},
3288+
TextDelta::Retain {
3289+
retain: 1,
3290+
attributes: Some(fx_map! { "bold".into() => LoroValue::Bool(true), "italic".into() => LoroValue::Bool(true) }),
3291+
},
3292+
]).unwrap();
3293+
assert_eq!(
3294+
doc.get_text("text").to_delta(),
3295+
vec![
3296+
TextDelta::Insert {
3297+
insert: "Hello".to_string(),
3298+
attributes: None,
3299+
},
3300+
TextDelta::Insert {
3301+
insert: "\n".to_string(),
3302+
attributes: Some(
3303+
fx_map! { "bold".into() => LoroValue::Bool(true), "italic".into() => LoroValue::Bool(true) }
3304+
),
3305+
},
3306+
]
3307+
);
3308+
}

0 commit comments

Comments
 (0)