Просмотр исходного кода

fix: delete an empty block doesn't preserve properties for the next

related to https://github.com/logseq/db-test/issues/470
Tienson Qin 3 месяцев назад
Родитель
Сommit
3eab751feb

+ 50 - 0
clj-e2e/test/logseq/e2e/outliner_basic_test.clj

@@ -1,6 +1,7 @@
 (ns logseq.e2e.outliner-basic-test
   (:require
    [clojure.test :refer [deftest testing is use-fixtures]]
+   [logseq.e2e.assert :as assert]
    [logseq.e2e.block :as b]
    [logseq.e2e.fixtures :as fixtures]
    [logseq.e2e.keyboard :as k]
@@ -124,3 +125,52 @@
 
 (deftest delete-test-with-children-test
   (delete-test-with-children))
+
+(deftest delete-concat-test-2-blocks
+  (testing "Delete concat with empty block"
+    (b/new-blocks ["" "b2"])
+    (b/indent)
+    (k/arrow-up)
+    (k/delete)
+    (util/wait-editor-visible)
+    (is (= "b2" (util/get-edit-content)))
+    (util/exit-edit)
+    (is (= ["b2"] (util/get-page-blocks-contents)))))
+
+(deftest delete-concat-test-3-blocks
+  (testing "Delete concat with empty block"
+    (b/new-blocks ["" "b2" "b3"])
+    (b/indent)
+    (k/arrow-up)
+    (k/arrow-up)
+    (k/delete)
+    (util/wait-editor-visible)
+    (is (= "b2" (util/get-edit-content)))
+    (util/exit-edit)
+    (is (= ["b2" "b3"] (util/get-page-blocks-contents)))))
+
+(deftest delete-concat-test-with-children
+  (testing "Delete concat with children blocks"
+    (b/new-blocks ["" "b2" "b3"])
+    (b/indent)
+    (k/arrow-up)
+    (b/indent)
+    (k/arrow-up)
+    (k/delete)
+    (util/wait-editor-visible)
+    (is (= "" (util/get-edit-content)))
+    (is (= 3 (util/page-blocks-count)))))
+
+(deftest delete-concat-test-with-tag
+  (testing "Delete concat with tag"
+    (b/new-blocks ["" "b2"])
+    (b/indent)
+    (util/set-tag "tag1")
+    (k/arrow-up)
+    (k/delete)
+    (util/wait-editor-visible)
+    (is (= "b2" (util/get-edit-content)))
+    (util/exit-edit)
+    (assert/assert-is-visible
+     ".ls-block a.tag:has-text('tag1')")
+    (is (= ["b2"] (util/get-page-blocks-contents)))))

+ 28 - 3
src/main/frontend/handler/editor.cljs

@@ -801,10 +801,11 @@
 (declare expand-block!)
 
 (defn delete-block-inner!
-  [repo {:keys [block-id value format config block-container]}]
+  [repo {:keys [block-id value format config block-container current-block next-block delete-concat?]}]
   (when block-id
     (when-let [block-e (db/entity [:block/uuid block-id])]
-      (let [prev-block (db-model/get-prev (db/get-db) (:db/id block-e))]
+      (let [prev-block (db-model/get-prev (db/get-db) (:db/id block-e))
+            input-empty? (string/blank? (state/get-edit-content))]
         (cond
           (and (nil? prev-block)
                (nil? (:block/parent block-e)))
@@ -836,6 +837,27 @@
                        (db-model/hidden-page? (:block/page block))) ; embed page
                   nil
 
+                  (and concat-prev-block? input-empty? delete-concat?)
+                  (let [children (:block/_parent (db/entity (:db/id current-block)))]
+                    (p/do!
+                     (ui-outliner-tx/transact!
+                      transact-opts
+                      (when (= (:db/id current-block) (:db/id (:block/parent next-block)))
+                        (property-handler/set-block-properties!
+                         repo
+                         (:block/uuid next-block)
+                         {:block/parent (:db/id (:block/parent current-block))
+                          :block/order (:block/order current-block)}))
+
+                      (when (seq children)
+                        (outliner-op/move-blocks!
+                         (remove (fn [c] (= (:db/id c) (:db/id next-block))) children)
+                         next-block
+                         {:sibling? false}))
+
+                      (delete-block-aux! current-block))
+                     (edit-block! (db/entity (:db/id next-block)) 0)))
+
                   concat-prev-block?
                   (let [children (:block/_parent (db/entity (:db/id block)))]
                     (p/do!
@@ -2745,7 +2767,10 @@
                                 :value (:block/title next-block)
                                 :block-container (util/get-next-block-non-collapsed
                                                   (util/rec-get-node (state/get-input) "ls-block")
-                                                  {:exclude-property? true}))]
+                                                  {:exclude-property? true})
+                                :current-block current-block
+                                :next-block next-block
+                                :delete-concat? true)]
         (delete-block-inner! repo editor-state)))))
 
 (defn keydown-delete-handler

+ 18 - 16
src/main/frontend/undo_redo.cljs

@@ -179,8 +179,8 @@
          [op e a v])))
    datoms))
 
-(defn- moved-block-or-target-deleted?
-  [conn e->datoms e moved-blocks redo?]
+(defn- block-moved-and-target-deleted?
+  [conn e->datoms e moved-blocks tx-data]
   (let [datoms (get e->datoms e)]
     (and (moved-blocks e)
          (let [b (d/entity @conn e)
@@ -188,16 +188,17 @@
                move-datoms (filter (fn [d] (contains? #{:block/parent} (:a d))) datoms)]
            (when cur-parent
              (let [before-parent (some (fn [d] (when (and (= :block/parent (:a d)) (not (:added d))) (:v d))) move-datoms)
-                   after-parent (some (fn [d] (when (and (= :block/parent (:a d)) (:added d)) (:v d))) move-datoms)]
-               (and before-parent after-parent ; parent changed
-                    (if redo?
-                      (or (not= cur-parent before-parent)
-                          (nil? (d/entity @conn after-parent)))
-                      (or (not= cur-parent after-parent)
-                          (nil? (d/entity @conn before-parent)))))))))))
+                   not-exists-in-current-db (nil? (d/entity @conn before-parent))
+                   ;; reverse tx-data will add parent before back
+                   removed-before-parent (some (fn [d] (and (= :block/uuid (:a d))
+                                                            (= before-parent (:e d))
+                                                            (not (:added d)))) tx-data)]
+               (and before-parent
+                    not-exists-in-current-db
+                    (not removed-before-parent))))))))
 
 (defn get-reversed-datoms
-  [conn undo? {:keys [tx-data added-ids retracted-ids] :as op} _tx-meta]
+  [conn undo? {:keys [tx-data added-ids retracted-ids] :as op} tx-meta]
   (try
     (let [redo? (not undo?)
           e->datoms (->> (if redo? tx-data (reverse tx-data))
@@ -218,16 +219,18 @@
                                          :undo? undo?})))
 
               ;; new children blocks have been added
-              (or (and (contains? retracted-ids e) redo?
-                       (other-children-exist? entity retracted-ids)) ; redo delete-blocks
-                  (and (contains? added-ids e) undo?                 ; undo insert-blocks
-                       (other-children-exist? entity added-ids)))
+              (and
+               (not (:local-tx? tx-meta))
+               (or (and (contains? retracted-ids e) redo?
+                        (other-children-exist? entity retracted-ids)) ; redo delete-blocks
+                   (and (contains? added-ids e) undo?                 ; undo insert-blocks
+                        (other-children-exist? entity added-ids))))
               (throw (ex-info "Children still exists"
                               (merge op {:error :block-children-exists
                                          :undo? undo?})))
 
               ;; block has been moved or target got deleted by another client
-              (moved-block-or-target-deleted? conn e->datoms e moved-blocks redo?)
+              (block-moved-and-target-deleted? conn e->datoms e moved-blocks tx-data)
               (throw (ex-info "This block has been moved or its target has been deleted"
                               (merge op {:error :block-moved-or-target-deleted
                                          :undo? undo?})))
@@ -238,7 +241,6 @@
                        (and (contains? added-ids e) undo?)))   ; undo insert-blocks
               [[:db/retractEntity e]]
 
-              ;; reverse datoms
               :else
               (reverse-datoms conn datoms schema added-ids retracted-ids undo? redo?))))
         e->datoms)

+ 1 - 1
src/main/frontend/worker/db_worker.cljs

@@ -533,7 +533,7 @@
       (catch :default e
         (prn :debug :error)
         (js/console.error e)
-        (prn :debug :tx-data @conn tx-data)))))
+        (prn :debug :tx-meta tx-meta :tx-data tx-data)))))
 
 (def-thread-api :thread-api/get-initial-data
   [repo]