mirror of
https://github.com/penpot/penpot.git
synced 2026-08-13 08:18:52 +00:00
110 lines
3.3 KiB
Clojure
110 lines
3.3 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC Sucursal en España SL
|
|
|
|
(ns app.util.clipboard
|
|
(:require
|
|
["./clipboard.js" :as impl]
|
|
[app.common.transit :as t]
|
|
[app.util.dom :as dom]
|
|
[beicon.v2.core :as rx]))
|
|
|
|
(def image-types
|
|
["image/webp"
|
|
"image/png"
|
|
"image/jpeg"
|
|
"image/svg+xml"])
|
|
|
|
(def ^:private default-options
|
|
#js {:decodeTransit t/decode-str
|
|
:allowHTMLPaste false})
|
|
|
|
(defn- from-data-transfer
|
|
"Get clipboard stream from DataTransfer instance"
|
|
([data-transfer]
|
|
(from-data-transfer data-transfer default-options))
|
|
([data-transfer options]
|
|
(->> (rx/from (impl/fromDataTransfer data-transfer options))
|
|
(rx/mapcat #(rx/from %)))))
|
|
|
|
(defn from-navigator
|
|
([]
|
|
(from-navigator default-options))
|
|
([options]
|
|
(->> (rx/from (impl/fromNavigator options))
|
|
(rx/mapcat #(rx/from %)))))
|
|
|
|
(defn from-clipboard-event
|
|
"Get clipboard stream from clipboard event"
|
|
([event]
|
|
(from-clipboard-event event default-options))
|
|
([event options]
|
|
(let [cdata (.-clipboardData ^js event)]
|
|
(from-data-transfer cdata options))))
|
|
|
|
(defn from-synthetic-clipboard-event
|
|
"Get clipboard stream from syntetic clipboard event"
|
|
([event options]
|
|
(let [target
|
|
(dom/get-target event)
|
|
|
|
content-editable?
|
|
(dom/is-content-editable? target)
|
|
|
|
is-input?
|
|
(= (dom/get-tag-name target) "INPUT")]
|
|
|
|
;; ignore when pasting into an editable control
|
|
(if-not (or content-editable? is-input?)
|
|
(-> event
|
|
(dom/event->browser-event)
|
|
(from-clipboard-event options))
|
|
(rx/empty)))))
|
|
|
|
(defn from-drop-event
|
|
"Get clipboard stream from drop event"
|
|
([event]
|
|
(from-drop-event event default-options))
|
|
([event options]
|
|
(from-data-transfer (.-dataTransfer ^js event) options)))
|
|
|
|
;; FIXME: rename to `write-text`
|
|
(defn to-clipboard
|
|
[data]
|
|
(assert (string? data) "`data` should be string")
|
|
(let [clipboard (unchecked-get js/navigator "clipboard")]
|
|
(.writeText ^js clipboard data)))
|
|
|
|
(defn- create-clipboard-item
|
|
[mimetype promise]
|
|
(js/ClipboardItem.
|
|
(js-obj mimetype promise)))
|
|
|
|
;; FIXME: this API is very confuse
|
|
(defn to-clipboard-promise
|
|
[mimetype promise]
|
|
(let [clipboard (unchecked-get js/navigator "clipboard")
|
|
data (create-clipboard-item mimetype promise)]
|
|
(.write ^js clipboard #js [data])))
|
|
|
|
(defn to-clipboard-multi
|
|
"Write multiple MIME representations as a single ClipboardItem.
|
|
`items` is a map of mime-type (string) -> string payload.
|
|
Falls back to `writeText` when the async Clipboard API is unavailable."
|
|
[items]
|
|
(let [clipboard (unchecked-get js/navigator "clipboard")]
|
|
(if (and clipboard (unchecked-get clipboard "write"))
|
|
(let [obj (reduce-kv
|
|
(fn [acc mime payload]
|
|
(let [blob (js/Blob. #js [payload] #js {:type mime})]
|
|
(unchecked-set acc mime (js/Promise.resolve blob))
|
|
acc))
|
|
#js {} items)
|
|
item (js/ClipboardItem. obj)]
|
|
(.write ^js clipboard #js [item]))
|
|
(when-let [text (or (get items "text/plain")
|
|
(first (vals items)))]
|
|
(.writeText ^js clipboard text)))))
|