Add general improvements to copy paste

Cleaning code and adding more safety checks
This commit is contained in:
Andrey Antukh 2023-11-22 09:37:48 +01:00
parent 37e4939af7
commit 783e0470be
11 changed files with 434 additions and 308 deletions

View file

@ -93,6 +93,10 @@
(create-blob content mtype)))
(defn get-current-selected-text
[]
(.. js/window getSelection toString))
(defn write-to-clipboard
[data]
(assert (string? data) "`data` should be string")
@ -101,44 +105,47 @@
(defn read-from-clipboard
[]
(let [cboard (unchecked-get js/navigator "clipboard")]
(if (.-readText ^js cboard)
(rx/from (.readText ^js cboard))
(throw (ex-info "This browser does not implement read from clipboard protocol"
{:not-implemented true})))))
(try
(let [cboard (unchecked-get js/navigator "clipboard")]
(if (.-readText ^js cboard)
(rx/from (.readText ^js cboard))
(rx/throw (ex-info "This browser does not implement read from clipboard protocol"
{:not-implemented true}))))
(catch :default cause
(rx/throw cause))))
(defn read-image-from-clipboard
[]
(let [cboard (unchecked-get js/navigator "clipboard")
read-item (fn [item]
(let [img-type (->> (.-types ^js item)
(d/seek #(str/starts-with? % "image/")))]
(if img-type
(rx/from (.getType ^js item img-type))
(rx/empty))))]
(->> (rx/from (.read ^js cboard)) ;; Get a stream of item lists
(rx/mapcat identity) ;; Convert each item into an emission
(rx/switch-map read-item))))
(try
(let [cboard (unchecked-get js/navigator "clipboard")
read-item (fn [item]
(let [img-type (->> (.-types ^js item)
(d/seek #(str/starts-with? % "image/")))]
(if img-type
(rx/from (.getType ^js item img-type))
(rx/empty))))]
(->> (rx/from (.read ^js cboard)) ;; Get a stream of item lists
(rx/mapcat identity) ;; Convert each item into an emission
(rx/switch-map read-item)))
(catch :default cause
(rx/throw cause))))
(defn read-from-paste-event
[event]
(let [target (.-target ^js event)]
(when (and (not (.-isContentEditable target)) ;; ignore when pasting into
(not= (.-tagName target) "INPUT")) ;; an editable control
(when (and (not (.-isContentEditable ^js target)) ;; ignore when pasting into
(not= (.-tagName ^js target) "INPUT")) ;; an editable control
(.. ^js event getBrowserEvent -clipboardData))))
(defn extract-text
[clipboard-data]
(when clipboard-data
(.getData clipboard-data "text")))
(.getData clipboard-data "text"))
(defn extract-images
"Get image files from clipboard data. Returns a native js array."
[clipboard-data]
(when clipboard-data
(let [file-list (-> (.-files ^js clipboard-data))]
(->> (range (.-length ^js file-list))
(map #(.item ^js file-list %))
(filter #(str/starts-with? (.-type %) "image/"))))))
(let [files (obj/into-array (.-files ^js clipboard-data))]
(.filter ^js files #(str/starts-with? (obj/get % "type") "image/"))))
(defn create-canvas-element
[width height]