Skip to content

Commit 85ad90f

Browse files
committed
Try to fix quill-editor load document error. Because Document can only contain insert operations
1 parent ddd0dec commit 85ad90f

File tree

4 files changed

+30
-49
lines changed

4 files changed

+30
-49
lines changed

frontend/rust-lib/flowy-document/src/core/revision/manager.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use flowy_error::FlowyResult;
1515
use futures_util::{future, stream, stream::StreamExt};
1616
use lib_infra::future::FutureResult;
1717
use lib_ot::{
18-
core::{Operation, OperationTransformable},
18+
core::{trim, Operation, OperationTransformable},
1919
errors::OTError,
2020
rich_text::RichTextDelta,
2121
};
@@ -259,11 +259,13 @@ fn mk_doc_from_revisions(doc_id: &str, revisions: Vec<Revision>) -> FlowyResult<
259259
base_rev_id,
260260
})
261261
}
262+
262263
fn correct_delta_if_need(delta: &mut RichTextDelta) {
264+
trim(delta);
265+
263266
if delta.ops.last().is_none() {
264267
return;
265268
}
266-
267269
let data = delta.ops.last().as_ref().unwrap().get_data();
268270
if !data.ends_with('\n') {
269271
log::error!("❌The op must end with newline. Correcting it by inserting newline op");

shared-lib/flowy-collaboration/src/document/document.rs

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
use tokio::sync::mpsc;
2-
3-
use lib_ot::{
4-
core::*,
5-
rich_text::{RichTextAttribute, RichTextDelta},
6-
};
7-
81
use crate::{
92
document::{
103
default::initial_delta,
@@ -13,6 +6,11 @@ use crate::{
136
},
147
errors::CollaborateError,
158
};
9+
use lib_ot::{
10+
core::*,
11+
rich_text::{RichTextAttribute, RichTextDelta},
12+
};
13+
use tokio::sync::mpsc;
1614

1715
pub trait InitialDocumentText {
1816
fn initial_delta() -> RichTextDelta;
@@ -81,12 +79,10 @@ impl Document {
8179
}
8280
}
8381

84-
pub fn compose_delta(&mut self, mut delta: RichTextDelta) -> Result<(), CollaborateError> {
82+
pub fn compose_delta(&mut self, delta: RichTextDelta) -> Result<(), CollaborateError> {
8583
tracing::trace!("👉 receive change: {}", delta);
86-
87-
trim(&mut delta);
8884
tracing::trace!("{} compose {}", &self.delta.to_json(), delta.to_json());
89-
let mut composed_delta = self.delta.compose(&delta)?;
85+
let composed_delta = self.delta.compose(&delta)?;
9086
let mut undo_delta = delta.invert(&self.delta);
9187

9288
let now = chrono::Utc::now().timestamp_millis() as usize;
@@ -107,7 +103,6 @@ impl Document {
107103
}
108104

109105
tracing::trace!("compose result: {}", composed_delta.to_json());
110-
trim(&mut composed_delta);
111106

112107
self.set_delta(composed_delta);
113108
Ok(())
@@ -171,11 +166,9 @@ impl Document {
171166
None => Err(CollaborateError::undo().context("Undo stack is empty")),
172167
Some(undo_delta) => {
173168
let (new_delta, inverted_delta) = self.invert(&undo_delta)?;
174-
let result = UndoResult::success(new_delta.target_len as usize);
175169
self.set_delta(new_delta);
176170
self.history.add_redo(inverted_delta);
177-
178-
Ok(result)
171+
Ok(UndoResult { delta: undo_delta })
179172
},
180173
}
181174
}
@@ -185,11 +178,9 @@ impl Document {
185178
None => Err(CollaborateError::redo()),
186179
Some(redo_delta) => {
187180
let (new_delta, inverted_delta) = self.invert(&redo_delta)?;
188-
let result = UndoResult::success(new_delta.target_len as usize);
189181
self.set_delta(new_delta);
190-
191182
self.history.add_undo(inverted_delta);
192-
Ok(result)
183+
Ok(UndoResult { delta: redo_delta })
193184
},
194185
}
195186
}
@@ -216,12 +207,3 @@ fn validate_interval(delta: &RichTextDelta, interval: &Interval) -> Result<(), C
216207
}
217208
Ok(())
218209
}
219-
220-
/// Removes trailing retain operation with empty attributes, if present.
221-
pub fn trim(delta: &mut RichTextDelta) {
222-
if let Some(last) = delta.ops.last() {
223-
if last.is_retain() && last.is_plain() {
224-
delta.ops.pop();
225-
}
226-
}
227-
}

shared-lib/lib-ot/src/core/delta/builder.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::core::{Attributes, Delta, Operation};
1+
use crate::core::{trim, Attributes, Delta, Operation};
22

33
pub struct DeltaBuilder<T: Attributes> {
44
delta: Delta<T>,
@@ -49,17 +49,3 @@ where
4949

5050
pub fn build(self) -> Delta<T> { self.delta }
5151
}
52-
53-
pub fn trim<T: Attributes>(delta: &mut Delta<T>) {
54-
let remove_last = match delta.ops.last() {
55-
None => false,
56-
Some(op) => match op {
57-
Operation::Delete(_) => false,
58-
Operation::Retain(retain) => retain.is_plain(),
59-
Operation::Insert(_) => false,
60-
},
61-
};
62-
if remove_last {
63-
delta.ops.pop();
64-
}
65-
}

shared-lib/lib-ot/src/core/delta/delta.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,17 +150,17 @@ where
150150
return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
151151
}
152152
let mut new_s = String::new();
153-
let chars = &mut s.chars();
153+
let utf16_iter = &mut s.utf16_iter();
154154
for op in &self.ops {
155155
match &op {
156156
Operation::Retain(retain) => {
157-
for c in chars.take(retain.n as usize) {
158-
new_s.push(c);
157+
for c in utf16_iter.take(retain.n as usize) {
158+
new_s.push_str(&c);
159159
}
160160
},
161161
Operation::Delete(delete) => {
162162
for _ in 0..*delete {
163-
chars.next();
163+
utf16_iter.next();
164164
}
165165
},
166166
Operation::Insert(insert) => {
@@ -264,7 +264,6 @@ where
264264
},
265265
}
266266
}
267-
268267
Ok(new_delta)
269268
}
270269

@@ -428,6 +427,18 @@ where
428427
}
429428
}
430429

430+
/// Removes trailing retain operation with empty attributes, if present.
431+
pub fn trim<T>(delta: &mut Delta<T>)
432+
where
433+
T: Attributes,
434+
{
435+
if let Some(last) = delta.ops.last() {
436+
if last.is_retain() && last.is_plain() {
437+
delta.ops.pop();
438+
}
439+
}
440+
}
441+
431442
fn invert_from_other<T: Attributes>(
432443
base: &mut Delta<T>,
433444
other: &Delta<T>,

0 commit comments

Comments
 (0)