Skip to content

Commit 0def48d

Browse files
committed
feat: transform patht
1 parent c61b4d0 commit 0def48d

File tree

5 files changed

+75
-6
lines changed

5 files changed

+75
-6
lines changed

frontend/app_flowy/packages/appflowy_editor/lib/src/operation/operation.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,10 @@ Path transformPath(Path preInsertPath, Path b, [int delta = 1]) {
207207

208208
Operation transformOperation(Operation a, Operation b) {
209209
if (a is InsertOperation) {
210-
final newPath = transformPath(a.path, b.path);
210+
final newPath = transformPath(a.path, b.path, a.nodes.length);
211211
return b.copyWithPath(newPath);
212212
} else if (a is DeleteOperation) {
213-
final newPath = transformPath(a.path, b.path, -1);
213+
final newPath = transformPath(a.path, b.path, -1 * a.nodes.length);
214214
return b.copyWithPath(newPath);
215215
}
216216
// TODO: transform update and textedit

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,15 @@ impl DocumentTree {
124124
return;
125125
}
126126

127+
let children_length = parent.children(&self.arena).fold(0, |counter, _| counter + 1);
128+
129+
if index == children_length {
130+
for id in insert_children {
131+
parent.append(*id, &mut self.arena);
132+
}
133+
return;
134+
}
135+
127136
let node_to_insert = self.child_at_index_of_path(parent, index).unwrap();
128137

129138
for id in insert_children {

shared-lib/lib-ot/src/core/document/document_operation.rs

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ pub enum DocumentOperation {
1010
}
1111

1212
impl DocumentOperation {
13+
pub fn path(&self) -> &Position {
14+
match self {
15+
DocumentOperation::Insert(insert) => &insert.path,
16+
DocumentOperation::Update(update) => &update.path,
17+
DocumentOperation::Delete(delete) => &delete.path,
18+
DocumentOperation::TextEdit(text_edit) => &text_edit.path,
19+
}
20+
}
1321
pub fn invert(&self) -> DocumentOperation {
1422
match self {
1523
DocumentOperation::Insert(insert_operation) => DocumentOperation::Delete(DeleteOperation {
@@ -32,8 +40,40 @@ impl DocumentOperation {
3240
}),
3341
}
3442
}
35-
pub fn transform(_a: &DocumentOperation, b: &DocumentOperation) -> DocumentOperation {
36-
b.clone()
43+
pub fn clone_with_new_path(&self, path: Position) -> DocumentOperation {
44+
match self {
45+
DocumentOperation::Insert(insert) => DocumentOperation::Insert(InsertOperation {
46+
path,
47+
nodes: insert.nodes.clone(),
48+
}),
49+
DocumentOperation::Update(update) => DocumentOperation::Update(UpdateOperation {
50+
path,
51+
attributes: update.attributes.clone(),
52+
old_attributes: update.old_attributes.clone(),
53+
}),
54+
DocumentOperation::Delete(delete) => DocumentOperation::Delete(DeleteOperation {
55+
path,
56+
nodes: delete.nodes.clone(),
57+
}),
58+
DocumentOperation::TextEdit(text_edit) => DocumentOperation::TextEdit(TextEditOperation {
59+
path,
60+
delta: text_edit.delta.clone(),
61+
inverted: text_edit.inverted.clone(),
62+
}),
63+
}
64+
}
65+
pub fn transform(a: &DocumentOperation, b: &DocumentOperation) -> DocumentOperation {
66+
match a {
67+
DocumentOperation::Insert(insert_op) => {
68+
let new_path = Position::transform(a.path(), b.path(), insert_op.nodes.len() as i64);
69+
b.clone_with_new_path(new_path)
70+
}
71+
DocumentOperation::Delete(delete_op) => {
72+
let new_path = Position::transform(a.path(), b.path(), delete_op.nodes.len() as i64);
73+
b.clone_with_new_path(new_path)
74+
}
75+
_ => b.clone(),
76+
}
3777
}
3878
}
3979

shared-lib/lib-ot/src/core/document/position.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ impl Position {
1212

1313
impl Position {
1414
// delta is default to be 1
15-
pub fn transform(pre_insert_path: &Position, b: &Position, delta: usize) -> Position {
15+
pub fn transform(pre_insert_path: &Position, b: &Position, delta: i64) -> Position {
1616
if pre_insert_path.len() > b.len() {
1717
return b.clone();
1818
}
@@ -30,7 +30,7 @@ impl Position {
3030
let prev_insert_last: usize = *pre_insert_path.0.last().unwrap();
3131
let b_at_index = b.0[pre_insert_path.0.len() - 1];
3232
if prev_insert_last <= b_at_index {
33-
prefix.push(b_at_index + delta);
33+
prefix.push(((b_at_index as i64) + delta) as usize);
3434
} else {
3535
prefix.push(b_at_index);
3636
}

shared-lib/lib-ot/tests/main.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,23 @@ fn test_documents() {
3434
document.apply(transaction);
3535
assert!(document.node_at_path(&vec![0].into()).is_none());
3636
}
37+
38+
#[test]
39+
fn test_transform_paths() {
40+
let mut document = DocumentTree::new();
41+
let transaction = {
42+
let mut tb = TransactionBuilder::new(&document);
43+
tb.insert_nodes(&vec![0].into(), &vec![NodeData::new("text")]);
44+
tb.insert_nodes(&vec![1].into(), &vec![NodeData::new("text")]);
45+
tb.insert_nodes(&vec![2].into(), &vec![NodeData::new("text")]);
46+
tb.finalize()
47+
};
48+
document.apply(transaction);
49+
50+
let transaction = {
51+
let mut tb = TransactionBuilder::new(&document);
52+
tb.insert_nodes(&vec![1].into(), &vec![NodeData::new("text")]);
53+
tb.finalize()
54+
};
55+
document.apply(transaction);
56+
}

0 commit comments

Comments
 (0)