Skip to content

Commit

Permalink
Fix rich text cursor pos (#324)
Browse files Browse the repository at this point in the history
* test: add text cursor test

* fix: should return event index
  • Loading branch information
zxch3n authored Apr 18, 2024
1 parent e8352ad commit 2fc4420
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/loro-internal/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,7 @@ impl DocState {
if let Some(id) = pos.id {
match state {
State::ListState(s) => s.get_index_of_id(id),
State::RichtextState(s) => s.get_index_of_id(id),
State::RichtextState(s) => s.get_event_index_of_id(id),
State::MapState(_) | State::TreeState(_) => {
unreachable!()
}
Expand Down
41 changes: 41 additions & 0 deletions crates/loro-internal/src/state/richtext_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,47 @@ impl RichtextState {

None
}

pub fn get_event_index_of_id(&self, id: ID) -> Option<usize> {
let iter: &mut dyn Iterator<Item = &RichtextStateChunk>;
let mut a;
let mut b;
match &self.state {
LazyLoad::Src(s) => {
a = Some(s.elements.iter());
iter = &mut *a.as_mut().unwrap();
}
LazyLoad::Dst(s) => {
b = Some(s.iter_chunk());
iter = &mut *b.as_mut().unwrap();
}
}

let mut index = 0;
for elem in iter {
let span = elem.get_id_span();
if span.contains(id) {
match elem {
RichtextStateChunk::Text(t) => {
let event_offset = t.convert_unicode_offset_to_event_offset(
(id.counter - span.counter.start) as usize,
);
return Some(index + event_offset);
}
RichtextStateChunk::Style { .. } => {
return Some(index);
}
}
}

index += match elem {
RichtextStateChunk::Text(t) => t.event_len() as usize,
RichtextStateChunk::Style { .. } => 0,
};
}

None
}
}

impl Clone for RichtextState {
Expand Down
10 changes: 10 additions & 0 deletions loro-js/tests/richtext.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,4 +267,14 @@ describe("richtext", () => {
expect(ans.update?.containerId()).toBe("cid:root-text:Text");
}
});

it("Styles should not affect cursor pos", () => {
const doc = new Loro();
const text = doc.getText("text");
text.insert(0, "Hello");
const pos3 = text.getCursor(3);
text.mark({ start: 0, end: 2 }, "bold", true);
const ans = doc.getCursorPos(pos3!);
expect(ans.offset).toBe(3);
});
});

0 comments on commit 2fc4420

Please sign in to comment.