mirror of https://github.com/logseq/logseq
fix(outliner): fix render
parent
9a75cb6431
commit
d4d4f9ee33
|
@ -81,14 +81,9 @@
|
|||
ids #{}
|
||||
parents #{}
|
||||
;; {[parent left] db-id}
|
||||
indexed-by-position {}
|
||||
|
||||
;; {db-id block}
|
||||
indexed-by-id {}]
|
||||
indexed-by-position {}]
|
||||
(if (nil? f)
|
||||
{:ids ids :parents parents
|
||||
:indexed-by-position indexed-by-position
|
||||
:indexed-by-id indexed-by-id}
|
||||
{:ids ids :parents parents :indexed-by-position indexed-by-position}
|
||||
(let [f (cond-> f
|
||||
(not (:block/dummy? f))
|
||||
(dissoc f :block/meta))
|
||||
|
@ -99,43 +94,16 @@
|
|||
(let [position (mapv ->db-id [parent left])]
|
||||
(when (get indexed-by-position position)
|
||||
(throw (js/Error. "Two block occupy the same position")))
|
||||
(assoc indexed-by-position position db-id))
|
||||
new-indexed-by-id
|
||||
(assoc indexed-by-id db-id f)]
|
||||
(recur r new-ids new-parents
|
||||
new-indexed-by-position new-indexed-by-id)))))
|
||||
(assoc indexed-by-position position f))]
|
||||
(recur r new-ids new-parents new-indexed-by-position)))))
|
||||
|
||||
(defn- find-last-node
|
||||
[root-node-id indexed-by-position indexed-by-id]
|
||||
"Root node is not in these blocks which be indexed. It should be the page
|
||||
block's :db/id."
|
||||
(assert (some? root-node-id) "root-node-id should satisfy some?.")
|
||||
(assert (and (map? indexed-by-position) (seq indexed-by-position))
|
||||
"indexed-position's format is wrong.")
|
||||
(assert (and (map? indexed-by-id) (seq indexed-by-id))
|
||||
"indexed-by-id's format is wrong.")
|
||||
(let [init-node {:db/id root-node-id}]
|
||||
(loop [node init-node
|
||||
;; from top to bottom
|
||||
;; direction :down :right
|
||||
direction :down]
|
||||
(case direction
|
||||
:down
|
||||
(let [id (:db/id node)]
|
||||
(if-let [new-node-db-id (get indexed-by-position [id id])]
|
||||
(let [new-node (get indexed-by-id new-node-db-id)]
|
||||
(recur new-node :right))
|
||||
node))
|
||||
|
||||
:right
|
||||
(let [{parent :block/parent db-id :db/id} node]
|
||||
(if-let [new-node-db-id
|
||||
(get indexed-by-position [(->db-id parent) db-id])]
|
||||
(let [new-node (get indexed-by-id new-node-db-id)]
|
||||
(recur new-node :right))
|
||||
(recur node :down)))
|
||||
|
||||
(throw (js/Error. (util/format "Unknown direction: %s" direction)))))))
|
||||
(defn get-children
|
||||
[parent-id indexed-by-position]
|
||||
(loop [left parent-id
|
||||
children []]
|
||||
(if-let [{db-id :db/id :as child} (get indexed-by-position [parent-id left])]
|
||||
(recur db-id (conj children child))
|
||||
children)))
|
||||
|
||||
(defn- get-all-refs
|
||||
[block]
|
||||
|
@ -154,36 +122,28 @@
|
|||
(cons block other-children)
|
||||
(mapcat get-all-refs)
|
||||
(remove nil?)
|
||||
distinct)))
|
||||
(distinct)
|
||||
(assoc block :block/refs-with-children))))
|
||||
|
||||
(defn blocks->vec-tree-by-outliner
|
||||
[col]
|
||||
(let [{:keys [ids parents indexed-by-position indexed-by-id]}
|
||||
(prn "col: " col)
|
||||
(let [{:keys [ids parents indexed-by-position]}
|
||||
(prepare-blocks col)
|
||||
root-id (first (set/difference parents ids))
|
||||
last-node (find-last-node root-id indexed-by-position indexed-by-id)
|
||||
last-node (wrap-refs-with-children last-node)]
|
||||
(loop [{:block/keys [parent left] :as node} last-node
|
||||
tree (list node)
|
||||
;; from bottom to top
|
||||
;; direction :up :left
|
||||
direction (if (= parent left) :up :left)]
|
||||
(if-let [left-node (get indexed-by-id (->db-id left))]
|
||||
(let [new-direction
|
||||
(if (= (:block/parent left-node)
|
||||
(:block/left left-node))
|
||||
:up :left)
|
||||
left-node (wrap-refs-with-children left-node)]
|
||||
(case direction
|
||||
:left
|
||||
(recur left-node (conj tree left-node) new-direction)
|
||||
:up
|
||||
(let [refs-with-children (wrap-refs-with-children left-node tree)
|
||||
new-ks {:block/children tree
|
||||
:block/refs-with-children refs-with-children}
|
||||
tree (merge left-node new-ks)]
|
||||
(recur left-node (list tree) new-direction))))
|
||||
tree))))
|
||||
root-id (first (set/difference parents ids))]
|
||||
(letfn [(build-tree [root]
|
||||
(let [root (wrap-refs-with-children root)
|
||||
children (->>
|
||||
(get-children (:db/id root) indexed-by-position)
|
||||
(map build-tree))]
|
||||
(if (seq children)
|
||||
(->
|
||||
(assoc root :block/children children)
|
||||
(wrap-refs-with-children children))
|
||||
root)))]
|
||||
(->>
|
||||
(get-children root-id indexed-by-position)
|
||||
(map build-tree)))))
|
||||
|
||||
;; recursively with children content for tree
|
||||
(defn get-block-content-rec
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[cljs-run-test :refer [run-test]]
|
||||
[frontend.handler.block :as block]))
|
||||
|
||||
(def blocks->vec-tree-sequential-block-args
|
||||
(def args-1
|
||||
'[{:block/parent {:db/id 20},
|
||||
:block/left {:db/id 20},
|
||||
:db/id 25
|
||||
|
@ -35,7 +35,8 @@
|
|||
:block/title [],
|
||||
:block/level 4}])
|
||||
|
||||
(def blocks->vec-tree-random-block-args
|
||||
(def args-2
|
||||
"Random blocks"
|
||||
'[{:block/parent {:db/id 26},
|
||||
:block/left {:db/id 26},
|
||||
:db/id 27
|
||||
|
@ -67,7 +68,7 @@
|
|||
:block/title [["Plain" "level 3"]],
|
||||
:block/level 4}])
|
||||
|
||||
(def blocks->vec-tree-return
|
||||
(def return-1
|
||||
'[{:block/parent {:db/id 20},
|
||||
:block/left {:db/id 20},
|
||||
:db/id 25,
|
||||
|
@ -106,15 +107,99 @@
|
|||
:block/level 4,
|
||||
:block/refs-with-children ()})})}])
|
||||
|
||||
(def args-3
|
||||
'({:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 20},
|
||||
:block/pre-block? true,
|
||||
:block/uuid #uuid"6061b993-6d08-4f32-9776-dcd2e506bce9",
|
||||
:block/level 2,
|
||||
:db/id 23}
|
||||
{:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 23},
|
||||
:block/uuid #uuid"6061b993-4e38-4b14-a698-f04c009d27fa",
|
||||
:block/level 2,
|
||||
:block/title [["Plain" "level 1"]],
|
||||
:db/id 24}
|
||||
{:block/parent #:db{:id 24},
|
||||
:block/left #:db{:id 24},
|
||||
:block/uuid #uuid"6061b993-a371-4cf7-a5ca-17e451489f89",
|
||||
:block/level 3,
|
||||
:block/title [["Plain" "level 1-1"]],
|
||||
:db/id 25}
|
||||
{:block/parent #:db{:id 25},
|
||||
:block/left #:db{:id 25},
|
||||
:block/uuid #uuid"6061b993-c13e-48c2-b6f0-bd7977134149",
|
||||
:block/level 4,
|
||||
:block/title [["Plain" "level 1-1-1"]],
|
||||
:db/id 26}
|
||||
{:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 24},
|
||||
:block/uuid #uuid"6061b993-9f37-4590-9f6f-c4ee789053be",
|
||||
:block/level 2,
|
||||
:block/title [["Plain" "level 2"]],
|
||||
:db/id 27}))
|
||||
|
||||
(def return-3
|
||||
'({:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 20},
|
||||
:block/pre-block? true,
|
||||
:block/uuid #uuid"6061b993-6d08-4f32-9776-dcd2e506bce9",
|
||||
:block/level 2,
|
||||
:db/id 23,
|
||||
:block/refs-with-children ()}
|
||||
{:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 23},
|
||||
:block/uuid #uuid"6061b993-4e38-4b14-a698-f04c009d27fa",
|
||||
:block/level 2,
|
||||
:block/title [["Plain" "level 1"]],
|
||||
:db/id 24,
|
||||
:block/refs-with-children (),
|
||||
:block/children ({:block/parent #:db{:id 24},
|
||||
:block/left #:db{:id 24},
|
||||
:block/uuid #uuid"6061b993-a371-4cf7-a5ca-17e451489f89",
|
||||
:block/level 3,
|
||||
:block/title [["Plain" "level 1-1"]],
|
||||
:db/id 25,
|
||||
:block/refs-with-children (),
|
||||
:block/children ({:block/parent #:db{:id 25},
|
||||
:block/left #:db{:id 25},
|
||||
:block/uuid #uuid"6061b993-c13e-48c2-b6f0-bd7977134149",
|
||||
:block/level 4,
|
||||
:block/title [["Plain" "level 1-1-1"]],
|
||||
:db/id 26,
|
||||
:block/refs-with-children ()})})}
|
||||
{:block/parent #:db{:id 20},
|
||||
:block/left #:db{:id 24},
|
||||
:block/uuid #uuid"6061b993-9f37-4590-9f6f-c4ee789053be",
|
||||
:block/level 2,
|
||||
:block/title [["Plain" "level 2"]],
|
||||
:db/id 27,
|
||||
:block/refs-with-children ()}))
|
||||
|
||||
(deftest test-blocks->vec-tree
|
||||
(let [should-r (vec blocks->vec-tree-return)]
|
||||
(let [r (block/blocks->vec-tree blocks->vec-tree-sequential-block-args)]
|
||||
(let [should-r (vec return-1)
|
||||
r (block/blocks->vec-tree args-1)]
|
||||
(is (= should-r (vec r))))
|
||||
|
||||
(let [r (block/blocks->vec-tree-by-outliner blocks->vec-tree-sequential-block-args)]
|
||||
(is (= should-r (vec r))))))
|
||||
(let [should-r (vec return-3)
|
||||
r (block/blocks->vec-tree args-3)]
|
||||
(is (= should-r (vec r)))))
|
||||
|
||||
(deftest test-blocks->vec-tree-random-block
|
||||
(let [should-r (vec blocks->vec-tree-return)
|
||||
r (block/blocks->vec-tree-by-outliner blocks->vec-tree-random-block-args)]
|
||||
(let [should-r (vec return-1)
|
||||
r (block/blocks->vec-tree-by-outliner args-1)]
|
||||
(is (= should-r (vec r))))
|
||||
|
||||
(let [should-r (vec return-1)
|
||||
r (block/blocks->vec-tree-by-outliner args-2)]
|
||||
(is (= should-r (vec r))))
|
||||
|
||||
(let [should-r (vec return-3)
|
||||
r (block/blocks->vec-tree-by-outliner args-3)]
|
||||
(is (= should-r (vec r)))))
|
||||
|
||||
(comment
|
||||
(defn clip-fn [x]
|
||||
(map #(select-keys % [:block/parent :block/left :block/pre-block? :block/uuid :block/level
|
||||
:block/title :db/id])
|
||||
x)))
|
||||
|
|
Loading…
Reference in New Issue