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) {
|
Operation transformOperation(Operation a, Operation b) {
|
||||||
if (a is InsertOperation) {
|
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);
|
return b.copyWithPath(newPath);
|
||||||
} else if (a is DeleteOperation) {
|
} 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);
|
return b.copyWithPath(newPath);
|
||||||
}
|
}
|
||||||
// TODO: transform update and textedit
|
// TODO: transform update and textedit
|
||||||
|
@ -124,6 +124,15 @@ impl DocumentTree {
|
|||||||
return;
|
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();
|
let node_to_insert = self.child_at_index_of_path(parent, index).unwrap();
|
||||||
|
|
||||||
for id in insert_children {
|
for id in insert_children {
|
||||||
|
@ -10,6 +10,14 @@ pub enum DocumentOperation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
pub fn invert(&self) -> DocumentOperation {
|
||||||
match self {
|
match self {
|
||||||
DocumentOperation::Insert(insert_operation) => DocumentOperation::Delete(DeleteOperation {
|
DocumentOperation::Insert(insert_operation) => DocumentOperation::Delete(DeleteOperation {
|
||||||
@ -32,8 +40,40 @@ impl DocumentOperation {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn transform(_a: &DocumentOperation, b: &DocumentOperation) -> DocumentOperation {
|
pub fn clone_with_new_path(&self, path: Position) -> DocumentOperation {
|
||||||
b.clone()
|
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 {
|
impl Position {
|
||||||
// delta is default to be 1
|
// 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() {
|
if pre_insert_path.len() > b.len() {
|
||||||
return b.clone();
|
return b.clone();
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ impl Position {
|
|||||||
let prev_insert_last: usize = *pre_insert_path.0.last().unwrap();
|
let prev_insert_last: usize = *pre_insert_path.0.last().unwrap();
|
||||||
let b_at_index = b.0[pre_insert_path.0.len() - 1];
|
let b_at_index = b.0[pre_insert_path.0.len() - 1];
|
||||||
if prev_insert_last <= b_at_index {
|
if prev_insert_last <= b_at_index {
|
||||||
prefix.push(b_at_index + delta);
|
prefix.push(((b_at_index as i64) + delta) as usize);
|
||||||
} else {
|
} else {
|
||||||
prefix.push(b_at_index);
|
prefix.push(b_at_index);
|
||||||
}
|
}
|
||||||
|
@ -34,3 +34,23 @@ fn test_documents() {
|
|||||||
document.apply(transaction);
|
document.apply(transaction);
|
||||||
assert!(document.node_at_path(&vec![0].into()).is_none());
|
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