Browse Source

feat: update attributes

Vincent Chan 2 years ago
parent
commit
8401fa0983

+ 1 - 1
shared-lib/lib-ot/src/core/document/attributes.rs

@@ -1,7 +1,7 @@
 use std::collections::HashMap;
 
 #[derive(Clone)]
-pub struct NodeAttributes(HashMap<String, Option<String>>);
+pub struct NodeAttributes(pub HashMap<String, Option<String>>);
 
 impl NodeAttributes {
     pub fn new() -> NodeAttributes {

+ 23 - 1
shared-lib/lib-ot/src/core/document/transaction.rs

@@ -1,5 +1,6 @@
+use std::collections::HashMap;
 use crate::core::document::position::Position;
-use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeData};
+use crate::core::{DeleteOperation, DocumentOperation, DocumentTree, InsertOperation, NodeAttributes, NodeData, UpdateOperation};
 
 pub struct Transaction {
     pub operations: Vec<DocumentOperation>,
@@ -31,6 +32,27 @@ impl<'a> TransactionBuilder<'a> {
         }));
     }
 
+    pub fn update_attributes(&mut self, path: &Position, attributes: HashMap<String, Option<String>>) {
+        let mut old_attributes: HashMap<String, Option<String>> = HashMap::new();
+        let node = self.document.node_at_path(path).unwrap();
+        let node_data = self.document.arena.get(node).unwrap().get();
+
+        for key in attributes.keys() {
+            let old_attrs = node_data.attributes.borrow();
+            let old_value = match old_attrs.0.get(key.as_str()) {
+                Some(value) => value.clone(),
+                None => None,
+            };
+            old_attributes.insert(key.clone(), old_value);
+        }
+
+        self.push(DocumentOperation::Update(UpdateOperation {
+            path: path.clone(),
+            attributes: NodeAttributes(attributes),
+            old_attributes: NodeAttributes(old_attributes),
+        }))
+    }
+
     pub fn delete_node(&mut self, path: &Position) {
         self.delete_nodes(path, 1);
     }

+ 14 - 1
shared-lib/lib-ot/tests/main.rs

@@ -1,3 +1,4 @@
+use std::collections::HashMap;
 use lib_ot::core::{DocumentTree, NodeData, Position, TransactionBuilder};
 
 #[test]
@@ -10,7 +11,19 @@ fn main() {
 fn test_documents() {
     let mut document = DocumentTree::new();
     let mut tb = TransactionBuilder::new(&document);
-    tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("type")]);
+    tb.insert_nodes(&Position(vec![0]), &vec![NodeData::new("text")]);
+    let transaction = tb.finalize();
+    document.apply(transaction);
+
+    assert!(document.node_at_path(&Position(vec![0])).is_some());
+    let node = document.node_at_path(&Position(vec![0])).unwrap();
+    let node_data = document.arena.get(node).unwrap().get();
+    assert_eq!(node_data.node_type, "text");
+
+    let mut tb = TransactionBuilder::new(&document);
+    tb.update_attributes(&Position(vec![0]), HashMap::from([
+        ("subtype".into(), Some("bullet-list".into())),
+    ]));
     let transaction = tb.finalize();
     document.apply(transaction);
 }