|
@@ -353,8 +353,16 @@
|
|
|
block (apply dissoc block db-schema/retract-attributes)]
|
|
|
(profile
|
|
|
"Save block: "
|
|
|
- (let [block' (wrap-parse-block block)
|
|
|
- opts' (merge opts {:outliner-op :save-block})]
|
|
|
+ (let [original-uuid (:block/uuid (db/entity (:db/id block)))
|
|
|
+ uuid-changed? (not= (:block/uuid block) original-uuid)
|
|
|
+ block' (-> (wrap-parse-block block)
|
|
|
+ ;; :block/uuid might be changed when backspace/delete
|
|
|
+ ;; a block that has been refed
|
|
|
+ (assoc :block/uuid (:block/uuid block)))
|
|
|
+ opts' (merge opts (cond-> {:outliner-op :save-block}
|
|
|
+ uuid-changed?
|
|
|
+ (assoc :uuid-changed {:from (:block/uuid block)
|
|
|
+ :to original-uuid})))]
|
|
|
(outliner-tx/transact!
|
|
|
opts'
|
|
|
(outliner-core/save-block! block'))
|
|
@@ -383,7 +391,8 @@
|
|
|
content (-> (property/remove-built-in-properties format content)
|
|
|
(drawer/remove-logbook))]
|
|
|
(cond
|
|
|
- (another-block-with-same-id-exists? uuid block-id)
|
|
|
+ (and (another-block-with-same-id-exists? uuid block-id)
|
|
|
+ (not (= :delete (:editor/op opts))))
|
|
|
(notification/show!
|
|
|
[:p.content
|
|
|
(util/format "Block with the id %s already exists!" block-id)]
|
|
@@ -760,6 +769,9 @@
|
|
|
(let [original-content (util/trim-safe (:block/content block))
|
|
|
value' (-> (property/remove-built-in-properties format original-content)
|
|
|
(drawer/remove-logbook))
|
|
|
+ value (->> value
|
|
|
+ (property/remove-properties format)
|
|
|
+ (drawer/remove-logbook))
|
|
|
new-value (str value' value)
|
|
|
tail-len (count value)
|
|
|
pos (max
|
|
@@ -767,10 +779,12 @@
|
|
|
(gobj/get (utf8/encode original-content) "length")
|
|
|
0)
|
|
|
0)
|
|
|
- f (fn [] (edit-block! block pos id
|
|
|
- {:custom-content new-value
|
|
|
- :tail-len tail-len
|
|
|
- :move-cursor? false}))]
|
|
|
+ f (fn []
|
|
|
+ (edit-block! (db/pull (:db/id block))
|
|
|
+ pos
|
|
|
+ id
|
|
|
+ {:custom-content new-value
|
|
|
+ :tail-len tail-len}))]
|
|
|
(when move? (f))
|
|
|
{:prev-block block
|
|
|
:new-content new-value
|
|
@@ -788,9 +802,9 @@
|
|
|
(let [page-id (:db/id (:block/page (db/entity [:block/uuid block-id])))
|
|
|
page-blocks-count (and page-id (db/get-page-blocks-count repo page-id))]
|
|
|
(when (> page-blocks-count 1)
|
|
|
- (let [block (db/entity [:block/uuid block-id])
|
|
|
- has-children? (seq (:block/_parent block))
|
|
|
- block (db/pull (:db/id block))
|
|
|
+ (let [block-e (db/entity [:block/uuid block-id])
|
|
|
+ has-children? (seq (:block/_parent block-e))
|
|
|
+ block (db/pull (:db/id block-e))
|
|
|
left (tree/-get-left (outliner-core/block block))
|
|
|
left-has-children? (and left
|
|
|
(when-let [block-id (:block/uuid (:data left))]
|
|
@@ -803,14 +817,20 @@
|
|
|
{: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)}))]
|
|
|
(outliner-tx/transact! transact-opts
|
|
|
- (when concat-prev-block?
|
|
|
- (save-block! repo prev-block new-content))
|
|
|
- (delete-block-aux! block delete-children?))
|
|
|
+ (if concat-prev-block?
|
|
|
+ (let [prev-block' (if (seq (:block/_refs block-e))
|
|
|
+ (assoc prev-block
|
|
|
+ :block/uuid (:block/uuid block)
|
|
|
+ :block/additional-properties (:block/properties block))
|
|
|
+ prev-block)]
|
|
|
+ (delete-block-aux! block delete-children?)
|
|
|
+ (save-block! repo prev-block' new-content {:editor/op :delete}))
|
|
|
+ (delete-block-aux! block delete-children?)))
|
|
|
(move-fn)))))))))
|
|
|
(state/set-editor-op! nil)))
|
|
|
|
|
@@ -1224,28 +1244,24 @@
|
|
|
(let [value (string/trim value)]
|
|
|
;; FIXME: somehow frontend.components.editor's will-unmount event will loop forever
|
|
|
;; maybe we shouldn't save the block/file in "will-unmount" event?
|
|
|
- (save-block-if-changed! block value
|
|
|
- (merge
|
|
|
- {:init-properties (:block/properties block)}
|
|
|
- opts))))
|
|
|
+ (save-block-if-changed! block value opts)))
|
|
|
|
|
|
(defn save-block!
|
|
|
([repo block-or-uuid content]
|
|
|
(save-block! repo block-or-uuid content {}))
|
|
|
- ([repo block-or-uuid content {:keys [properties] :or {}}]
|
|
|
+ ([repo block-or-uuid content {:keys [properties] :as opts}]
|
|
|
(let [block (if (or (uuid? block-or-uuid)
|
|
|
(string? block-or-uuid))
|
|
|
(db-model/query-block-by-uuid block-or-uuid) block-or-uuid)]
|
|
|
(save-block!
|
|
|
- {:block block :repo repo}
|
|
|
- (if (seq properties)
|
|
|
- (property/insert-properties (:block/format block) content properties)
|
|
|
- content)
|
|
|
- )))
|
|
|
- ([{:keys [block repo] :as _state} value]
|
|
|
+ {:block block :repo repo :opts (dissoc opts :properties)}
|
|
|
+ (if (seq properties)
|
|
|
+ (property/insert-properties (:block/format block) content properties)
|
|
|
+ content))))
|
|
|
+ ([{:keys [block repo opts] :as _state} value]
|
|
|
(let [repo (or repo (state/get-current-repo))]
|
|
|
(when (db/entity repo [:block/uuid (:block/uuid block)])
|
|
|
- (save-block-aux! block value {})))))
|
|
|
+ (save-block-aux! block value opts)))))
|
|
|
|
|
|
(defn save-blocks!
|
|
|
[blocks]
|
|
@@ -1539,7 +1555,7 @@
|
|
|
"$" "$"
|
|
|
":" ":"))
|
|
|
|
|
|
-(defn autopair
|
|
|
+(defn- autopair
|
|
|
[input-id prefix _format _option]
|
|
|
(let [value (get autopair-map prefix)
|
|
|
selected (util/get-selected-text)
|
|
@@ -1576,11 +1592,11 @@
|
|
|
(defn- autopair-left-paren?
|
|
|
[input key]
|
|
|
(and (= key "(")
|
|
|
- (or
|
|
|
- (surround-by? input :start "")
|
|
|
- (surround-by? input " " "")
|
|
|
- (surround-by? input "]" "")
|
|
|
- (surround-by? input "(" ""))))
|
|
|
+ (or (surround-by? input :start "")
|
|
|
+ (surround-by? input "\n" "")
|
|
|
+ (surround-by? input " " "")
|
|
|
+ (surround-by? input "]" "")
|
|
|
+ (surround-by? input "(" ""))))
|
|
|
|
|
|
(defn wrapped-by?
|
|
|
[input before end]
|
|
@@ -1967,7 +1983,9 @@
|
|
|
exclude-properties
|
|
|
target-block
|
|
|
sibling?
|
|
|
- keep-uuid?]
|
|
|
+ keep-uuid?
|
|
|
+ cut-paste?
|
|
|
+ revert-cut-txs]
|
|
|
:or {exclude-properties []}}]
|
|
|
(let [editing-block (when-let [editing-block (state/get-edit-block)]
|
|
|
(some-> (db/pull [:block/uuid (:block/uuid editing-block)])
|
|
@@ -1982,8 +2000,7 @@
|
|
|
empty-target? (string/blank? (:block/content target-block))
|
|
|
paste-nested-blocks? (nested-blocks blocks)
|
|
|
target-block-has-children? (db/has-children? (:block/uuid target-block))
|
|
|
- replace-empty-target? (if (and paste-nested-blocks? empty-target?
|
|
|
- target-block-has-children?)
|
|
|
+ replace-empty-target? (if (and paste-nested-blocks? empty-target? target-block-has-children?)
|
|
|
false
|
|
|
true)
|
|
|
target-block' (if replace-empty-target? target-block
|
|
@@ -2009,13 +2026,15 @@
|
|
|
(outliner-core/save-block! editing-block)))
|
|
|
|
|
|
(outliner-tx/transact!
|
|
|
- {:outliner-op :insert-blocks}
|
|
|
+ {:outliner-op :insert-blocks
|
|
|
+ :additional-tx revert-cut-txs}
|
|
|
(when target-block'
|
|
|
(let [format (or (:block/format target-block') (state/get-preferred-format))
|
|
|
blocks' (map (fn [block]
|
|
|
(paste-block-cleanup block page exclude-properties format content-update-fn keep-uuid?))
|
|
|
blocks)
|
|
|
result (outliner-core/insert-blocks! blocks' target-block' {:sibling? sibling?
|
|
|
+ :cut-paste? cut-paste?
|
|
|
:outliner-op :paste
|
|
|
:replace-empty-target? replace-empty-target?
|
|
|
:keep-uuid? keep-uuid?})]
|
|
@@ -2205,10 +2224,18 @@
|
|
|
s1 (subs value 0 selected-start)
|
|
|
s2 (subs value selected-end)]
|
|
|
(state/set-edit-content! (state/get-edit-input-id)
|
|
|
- (str s1 insertion s2))
|
|
|
- (cursor/move-cursor-to input (+ selected-start (count insertion)))))))
|
|
|
+ (str s1 insertion))
|
|
|
+ ;; HACK: save scroll-pos of current pos, then add trailing content
|
|
|
+ ;; This logic is also in commands/simple-insert!
|
|
|
+ (let [scroll-container (util/nearest-scrollable-container input)
|
|
|
+ scroll-pos (.-scrollTop scroll-container)]
|
|
|
+ (state/set-edit-content! (state/get-edit-input-id)
|
|
|
+ (str s1 insertion s2))
|
|
|
+ (cursor/move-cursor-to input (+ selected-start (count insertion)))
|
|
|
+ (set! (.-scrollTop scroll-container) scroll-pos))))))
|
|
|
|
|
|
(defn- keydown-new-line
|
|
|
+ "Insert newline to current cursor position"
|
|
|
[]
|
|
|
(insert "\n"))
|
|
|
|
|
@@ -2434,7 +2461,6 @@
|
|
|
(profile
|
|
|
"Insert block"
|
|
|
(outliner-tx/transact! {:outliner-op :insert-blocks}
|
|
|
- (save-current-block!)
|
|
|
(insert-new-block! state)))))))))
|
|
|
|
|
|
(defn- inside-of-single-block
|
|
@@ -2585,8 +2611,7 @@
|
|
|
(state/set-edit-content! (state/get-edit-input-id) (.-value input)))
|
|
|
|
|
|
(defn- delete-concat [current-block]
|
|
|
- (let [input-id (state/get-edit-input-id)
|
|
|
- ^js input (state/get-input)
|
|
|
+ (let [^js input (state/get-input)
|
|
|
current-pos (cursor/pos input)
|
|
|
value (gobj/get input "value")
|
|
|
right (outliner-core/get-right-sibling (:db/id current-block))
|
|
@@ -2608,17 +2633,27 @@
|
|
|
|
|
|
: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}}
|
|
|
- new-content (str value "" (:block/content next-block))
|
|
|
- repo (state/get-current-repo)]
|
|
|
+ next-block-has-refs? (some? (:block/_refs (db/entity (:db/id next-block))))
|
|
|
+ new-content (if next-block-has-refs?
|
|
|
+ (str value ""
|
|
|
+ (->> (:block/content next-block)
|
|
|
+ (property/remove-properties (:block/format next-block))
|
|
|
+ (drawer/remove-logbook)))
|
|
|
+ (str value "" (:block/content next-block)))
|
|
|
+ repo (state/get-current-repo)
|
|
|
+ edit-block' (if next-block-has-refs?
|
|
|
+ (assoc edit-block
|
|
|
+ :block/uuid (:block/uuid next-block)
|
|
|
+ :block/additional-properties (dissoc (:block/properties next-block) :block/uuid))
|
|
|
+ edit-block)]
|
|
|
(outliner-tx/transact! transact-opts
|
|
|
- (save-block! repo edit-block new-content)
|
|
|
- (delete-block-aux! next-block false))
|
|
|
-
|
|
|
- (state/set-edit-content! input-id new-content)
|
|
|
- (cursor/move-cursor-to input current-pos)))))
|
|
|
+ (delete-block-aux! next-block false)
|
|
|
+ (save-block! repo edit-block' new-content {:editor/op :delete}))
|
|
|
+ (let [block (if next-block-has-refs? next-block edit-block)]
|
|
|
+ (edit-block! block current-pos (:block/uuid block)))))))
|
|
|
|
|
|
(defn keydown-delete-handler
|
|
|
[_e]
|
|
@@ -2832,11 +2867,11 @@
|
|
|
(contains? key)
|
|
|
(or (autopair-left-paren? input key)))
|
|
|
(let [curr (get-current-input-char input)
|
|
|
- prev (util/nth-safe value (dec pos))]
|
|
|
- (util/stop e)
|
|
|
- (if (and (= key "`") (= "`" curr) (not= "`" prev))
|
|
|
- (cursor/move-cursor-forward input)
|
|
|
- (autopair input-id key format nil)))
|
|
|
+ prev (util/nth-safe value (dec pos))]
|
|
|
+ (util/stop e)
|
|
|
+ (if (and (= key "`") (= "`" curr) (not= "`" prev))
|
|
|
+ (cursor/move-cursor-forward input)
|
|
|
+ (autopair input-id key format nil)))
|
|
|
|
|
|
(let [sym "$"]
|
|
|
(and (= key sym)
|