mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: transform patht
This commit is contained in:
parent
c61b4d0865
commit
0def48d0ca
@ -207,10 +207,10 @@ Path transformPath(Path preInsertPath, Path b, [int delta = 1]) {
|
||||
|
||||
Operation transformOperation(Operation a, Operation b) {
|
||||
if (a is InsertOperation) {
|
||||
final newPath = transformPath(a.path, b.path);
|
||||
final newPath = transformPath(a.path, b.path, a.nodes.length);
|
||||
return b.copyWithPath(newPath);
|
||||
} else if (a is DeleteOperation) {
|
||||
final newPath = transformPath(a.path, b.path, -1);
|
||||
final newPath = transformPath(a.path, b.path, -1 * a.nodes.length);
|
||||
return b.copyWithPath(newPath);
|
||||
}
|
||||
// TODO: transform update and textedit
|
||||
|
@ -124,6 +124,15 @@ impl DocumentTree {
|
||||
return;
|
||||
}
|
||||
|
||||
let children_length = parent.children(&self.arena).fold(0, |counter, _| counter + 1);
|
||||
|
||||
if index == children_length {
|
||||
for id in insert_children {
|
||||
parent.append(*id, &mut self.arena);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let node_to_insert = self.child_at_index_of_path(parent, index).unwrap();
|
||||
|
||||
for id in insert_children {
|
||||
|
@ -10,6 +10,14 @@ pub enum DocumentOperation {
|
||||
}
|
||||
|
||||
impl DocumentOperation {
|
||||
pub fn path(&self) -> &Position {
|
||||
match self {
|
||||
DocumentOperation::Insert(insert) => &insert.path,
|
||||
DocumentOperation::Update(update) => &update.path,
|
||||
DocumentOperation::Delete(delete) => &delete.path,
|
||||
DocumentOperation::TextEdit(text_edit) => &text_edit.path,
|
||||
}
|
||||
}
|
||||
pub fn invert(&self) -> DocumentOperation {
|
||||
match self {
|
||||
DocumentOperation::Insert(insert_operation) => DocumentOperation::Delete(DeleteOperation {
|
||||
@ -32,8 +40,40 @@ impl DocumentOperation {
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn transform(_a: &DocumentOperation, b: &DocumentOperation) -> DocumentOperation {
|
||||
b.clone()
|
||||
pub fn clone_with_new_path(&self, path: Position) -> DocumentOperation {
|
||||
match self {
|
||||
DocumentOperation::Insert(insert) => DocumentOperation::Insert(InsertOperation {
|
||||
path,
|
||||
nodes: insert.nodes.clone(),
|
||||
}),
|
||||
DocumentOperation::Update(update) => DocumentOperation::Update(UpdateOperation {
|
||||
path,
|
||||
attributes: update.attributes.clone(),
|
||||
old_attributes: update.old_attributes.clone(),
|
||||
}),
|
||||
DocumentOperation::Delete(delete) => DocumentOperation::Delete(DeleteOperation {
|
||||
path,
|
||||
nodes: delete.nodes.clone(),
|
||||
}),
|
||||
DocumentOperation::TextEdit(text_edit) => DocumentOperation::TextEdit(TextEditOperation {
|
||||
path,
|
||||
delta: text_edit.delta.clone(),
|
||||
inverted: text_edit.inverted.clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
pub fn transform(a: &DocumentOperation, b: &DocumentOperation) -> DocumentOperation {
|
||||
match a {
|
||||
DocumentOperation::Insert(insert_op) => {
|
||||
let new_path = Position::transform(a.path(), b.path(), insert_op.nodes.len() as i64);
|
||||
b.clone_with_new_path(new_path)
|
||||
}
|
||||
DocumentOperation::Delete(delete_op) => {
|
||||
let new_path = Position::transform(a.path(), b.path(), delete_op.nodes.len() as i64);
|
||||
b.clone_with_new_path(new_path)
|
||||
}
|
||||
_ => b.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ impl Position {
|
||||
|
||||
impl Position {
|
||||
// delta is default to be 1
|
||||
pub fn transform(pre_insert_path: &Position, b: &Position, delta: usize) -> Position {
|
||||
pub fn transform(pre_insert_path: &Position, b: &Position, delta: i64) -> Position {
|
||||
if pre_insert_path.len() > b.len() {
|
||||
return b.clone();
|
||||
}
|
||||
@ -30,7 +30,7 @@ impl Position {
|
||||
let prev_insert_last: usize = *pre_insert_path.0.last().unwrap();
|
||||
let b_at_index = b.0[pre_insert_path.0.len() - 1];
|
||||
if prev_insert_last <= b_at_index {
|
||||
prefix.push(b_at_index + delta);
|
||||
prefix.push(((b_at_index as i64) + delta) as usize);
|
||||
} else {
|
||||
prefix.push(b_at_index);
|
||||
}
|
||||
|
@ -34,3 +34,23 @@ fn test_documents() {
|
||||
document.apply(transaction);
|
||||
assert!(document.node_at_path(&vec![0].into()).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_transform_paths() {
|
||||
let mut document = DocumentTree::new();
|
||||
let transaction = {
|
||||
let mut tb = TransactionBuilder::new(&document);
|
||||
tb.insert_nodes(&vec![0].into(), &vec![NodeData::new("text")]);
|
||||
tb.insert_nodes(&vec![1].into(), &vec![NodeData::new("text")]);
|
||||
tb.insert_nodes(&vec![2].into(), &vec![NodeData::new("text")]);
|
||||
tb.finalize()
|
||||
};
|
||||
document.apply(transaction);
|
||||
|
||||
let transaction = {
|
||||
let mut tb = TransactionBuilder::new(&document);
|
||||
tb.insert_nodes(&vec![1].into(), &vec![NodeData::new("text")]);
|
||||
tb.finalize()
|
||||
};
|
||||
document.apply(transaction);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user