فهرست منبع

fix: replace with source block's content when deleting refed blocks

Tienson Qin 2 سال پیش
والد
کامیت
affa57e78d

+ 2 - 2
src/main/frontend/handler/editor.cljs

@@ -808,7 +808,7 @@
                        {:keys [prev-block new-content move-fn]} (move-to-prev-block repo sibling-block format id value false)
                        concat-prev-block? (boolean (and prev-block new-content))
                        transact-opts (cond->
-                                       {:outliner-op :delete-block}
+                                       {:outliner-op :delete-blocks}
                                        concat-prev-block?
                                        (assoc :concat-data
                                               {:last-edit-block (:block/uuid block)}))]
@@ -2615,7 +2615,7 @@
 
       :else
       (let [edit-block (state/get-edit-block)
-            transact-opts {:outliner-op :delete-block
+            transact-opts {:outliner-op :delete-blocks
                            :concat-data {:last-edit-block (:block/uuid edit-block)
                                          :end? true}}
             next-block-has-refs? (some? (:block/_refs (db/entity (:db/id next-block))))

+ 37 - 8
src/main/frontend/modules/outliner/datascript.cljc

@@ -12,7 +12,9 @@
                      [logseq.graph-parser.util :as gp-util]
                      [lambdaisland.glogi :as log]
                      [frontend.search :as search]
-                     [clojure.string :as string])))
+                     [clojure.string :as string]
+                     [frontend.util :as util]
+                     [frontend.util.property :as property])))
 
 #?(:cljs
    (defn new-outliner-txs-state [] (atom [])))
@@ -65,21 +67,47 @@
              kept-refs (:block/_refs kept-e)
              kept-path-refs (:block/_path-refs kept-e)
              deleted-refs (:block/_refs deleted-e)
-             kept-refs-txs (mapcat (fn [ref refs]
+             kept-refs-txs (mapcat (fn [ref]
                                      (let [id (:db/id ref)]
                                        [[:db/retract id :block/refs kept-id]
                                         [:db/add id :block/refs deleted-id]])) kept-refs)
-             kept-path-refs-txs (mapcat (fn [ref refs]
+             kept-path-refs-txs (mapcat (fn [ref]
                                           (let [id (:db/id ref)]
                                             [[:db/retract id :block/path-refs kept-id]
                                              [:db/add id :block/path-refs deleted-id]])) kept-path-refs)
-             deleted-refs-txs (mapcat (fn [ref refs]
-                                     (let [id (:db/id ref)]
-                                       (let [new-content (string/replace (:block/content ref) (str deleted) (str kept))]
-                                         [[:db/add id :block/content new-content]]))) deleted-refs)]
+             deleted-refs-txs (mapcat (fn [ref]
+                                        (let [id (:db/id ref)
+                                              new-content (string/replace (:block/content ref) (str deleted) (str kept))]
+                                          [[:db/add id :block/content new-content]])) deleted-refs)]
          (concat txs kept-refs-txs kept-path-refs-txs deleted-refs-txs))
        txs)))
 
+#?(:cljs
+   (defn replace-ref-with-content
+     [txs opts]
+     (if (and (= :delete-blocks (:outliner-op opts))
+              (not (:uuid-changed opts)))
+       (let [retracted-blocks (->> (keep (fn [tx]
+                                           (when (and (vector? tx)
+                                                      (= :db.fn/retractEntity (first tx)))
+                                             (second tx))) txs)
+                                   (map db/entity))
+             retracted-tx (->> (for [block retracted-blocks]
+                                 (let [refs (:block/_refs block)]
+                                   (mapcat (fn [ref]
+                                             (let [id (:db/id ref)
+                                                   block-content (property/remove-properties (:block/format block) (:block/content block))
+                                                   new-content (-> (:block/content ref)
+                                                                   (string/replace (re-pattern (util/format "{{embed \\(\\(%s\\)\\)\\s?}}" (str (:block/uuid block))))
+                                                                                   block-content)
+                                                                   (string/replace (util/format "((%s))" (str (:block/uuid block)))
+                                                                                   block-content))]
+                                               [[:db/retract (:db/id ref) :block/refs (:db/id block)]
+                                                [:db/add id :block/content new-content]])) refs)))
+                               (apply concat))]
+         (concat txs retracted-tx))
+       txs)))
+
 #?(:cljs
    (defn transact!
      [txs opts before-editor-cursor]
@@ -92,6 +120,7 @@
                                       :block/additional-properties)
                               m)) txs)
            txs (-> (update-block-refs txs opts)
+                   (replace-ref-with-content opts)
                    (distinct))]
        (when (and (seq txs)
                   (not (:skip-transact? opts))
@@ -101,7 +130,7 @@
                                     (config/get-repo-dir repo)))))
 
          (prn "[DEBUG] Outliner transact:")
-         (frontend.util/pprint txs)
+         (frontend.util/pprint {:txs txs :opts opts})
 
          (try
            (let [repo (get opts :repo (state/get-current-repo))

+ 7 - 3
src/main/frontend/modules/outliner/transaction.cljc

@@ -23,18 +23,21 @@
     (move-blocks! ...)
     (delete-blocks! ...))"
   [opts & body]
-  (assert (or (map? opts) (symbol? opts)) (str "opts is not a map or symbol, type: " (type opts) ))
+  (assert (or (map? opts) (symbol? opts)) (str "opts is not a map or symbol, type: " (type opts)))
   `(let [transact-data# frontend.modules.outliner.core/*transaction-data*
          transaction-opts# frontend.modules.outliner.core/*transaction-opts*
          opts# (if transact-data#
                  (assoc ~opts :nested-transaction? true)
                  ~opts)
          before-editor-cursor# (frontend.state/get-current-edit-block-and-position)]
-     (when transaction-opts# (conj! transaction-opts# opts#))
      (if transact-data#
-       (do ~@body)
+       (do
+         (when transaction-opts#
+           (conj! transaction-opts# opts#))
+         ~@body)
        (binding [frontend.modules.outliner.core/*transaction-data* (transient [])
                  frontend.modules.outliner.core/*transaction-opts* (transient [])]
+         (conj! frontend.modules.outliner.core/*transaction-opts* transaction-opts# opts#)
          ~@body
          (let [r# (persistent! frontend.modules.outliner.core/*transaction-data*)
                tx# (mapcat :tx-data r#)
@@ -44,6 +47,7 @@
                o# (persistent! frontend.modules.outliner.core/*transaction-opts*)
                full-opts# (apply merge (reverse o#))
                opts## (merge (dissoc full-opts# :additional-tx :current-block :nested-transaction?) tx-meta#)]
+
            (when (seq all-tx#) ;; If it's empty, do nothing
              (when-not (:nested-transaction? opts#) ; transact only for the whole transaction
                (let [result# (frontend.modules.outliner.datascript/transact! all-tx# opts## before-editor-cursor#)]