Skip to content

Commit

Permalink
Split raw and formatted paste to prevent future coupling bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
logseq-cldwalker committed Mar 20, 2023
1 parent 72298d2 commit 7a90558
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 39 deletions.
82 changes: 47 additions & 35 deletions src/main/frontend/handler/paste.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -182,38 +182,50 @@
(paste-copied-blocks-or-text text e html)))

(defn editor-on-paste!
([id]
(editor-on-paste! id false))
([id raw-paste?]
(fn [e]
(state/set-state! :editor/on-paste? true)
(let [input (state/get-input)]
(if raw-paste?
(utils/getClipText
(fn [clipboard-data]
(when (state/get-input)
(editor-handler/insert clipboard-data true)))
(fn [error]
(js/console.error error)))
(let [clipboard-data (gobj/get e "clipboardData")
html (when-not raw-paste? (.getData clipboard-data "text/html"))
text (.getData clipboard-data "text")
files (.-files text)
paste-file-if-exist (fn []
(when id
(let [_handled
(let [clipboard-data (gobj/get e "clipboardData")
files (.-files clipboard-data)]
(when-let [file (first files)]
(when-let [block (state/get-edit-block)]
(editor-handler/upload-asset id #js[file] (:block/format block)
editor-handler/*asset-uploading? true))))]
(util/stop e))))]
(cond
(and (string/blank? text) (string/blank? html)) (paste-file-if-exist)
(and (seq files) (state/preferred-pasting-file?)) (paste-file-if-exist)
:else
(let [text' (or (when (gp-util/url? text)
(wrap-macro-url text))
text)]
(paste-text-or-blocks-aux input e text' html)))))))))
"Pastes with formatting and includes the following features:
- handles internal pastes to correctly paste at the block level
- formatted paste includes HTML if detected
- special handling for newline and new blocks
- pastes file if it exists
- wraps certain urls with macros
- wraps selected urls with link formatting
- whiteboard friendly pasting
- paste replaces selected text"
[id]
(fn [e]
(state/set-state! :editor/on-paste? true)
(let [input (state/get-input)
clipboard-data (gobj/get e "clipboardData")
html (.getData clipboard-data "text/html")
text (.getData clipboard-data "text")
files (.-files text)
paste-file-if-exist (fn []
(when id
(let [_handled
(let [clipboard-data (gobj/get e "clipboardData")
files (.-files clipboard-data)]
(when-let [file (first files)]
(when-let [block (state/get-edit-block)]
(editor-handler/upload-asset id #js[file] (:block/format block)
editor-handler/*asset-uploading? true))))]
(util/stop e))))]
(cond
(and (string/blank? text) (string/blank? html)) (paste-file-if-exist)
(and (seq files) (state/preferred-pasting-file?)) (paste-file-if-exist)
:else
(let [text' (or (when (gp-util/url? text)
(wrap-macro-url text))
text)]
(paste-text-or-blocks-aux input e text' html))))))

(defn editor-on-paste-raw!
"Raw pastes without _any_ formatting. Can also replace selected text with a paste"
[]
(state/set-state! :editor/on-paste? true)
(utils/getClipText
(fn [clipboard-data]
(when (state/get-input)
(commands/delete-selection! (state/get-edit-input-id))
(editor-handler/insert clipboard-data true)))
(fn [error]
(js/console.error error))))
2 changes: 1 addition & 1 deletion src/main/frontend/modules/shortcut/config.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@
:fn editor-handler/copy-current-block-embed}

:editor/paste-text-in-one-block-at-point {:binding "mod+shift+v"
:fn (fn [_state e] ((paste-handler/editor-on-paste! nil true) e))}
:fn paste-handler/editor-on-paste-raw!}

:editor/insert-youtube-timestamp {:binding "mod+shift+y"
:fn commands/insert-youtube-timestamp}
Expand Down
8 changes: 5 additions & 3 deletions src/test/frontend/handler/paste_test.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,22 @@
reset
[utils/getClipText (fn [cb] (cb clipboard))
state/get-input (constantly #js {:value "block"})
commands/delete-selection! (constantly nil)
editor-handler/insert (fn [text _] (p/resolved text))]
(p/let [result ((paste-handler/editor-on-paste! nil true))]
(p/let [result (paste-handler/editor-on-paste-raw!)]
(is (= expected-paste result))
(reset))))))

(deftest-async ^:focus editor-on-paste-raw-with-multi-line
(deftest-async editor-on-paste-raw-with-multi-line
(let [clipboard "a\n\na"
expected-paste "a\n\na"]
(test-helper/with-reset
reset
[utils/getClipText (fn [cb] (cb clipboard))
state/get-input (constantly #js {:value "block"})
commands/delete-selection! (constantly nil)
editor-handler/insert (fn [text _] (p/resolved text))]
(p/let [result ((paste-handler/editor-on-paste! nil true))]
(p/let [result (paste-handler/editor-on-paste-raw!)]
(is (= expected-paste result))
(reset)))))

Expand Down

0 comments on commit 7a90558

Please sign in to comment.