mirror of
https://github.com/penpot/penpot.git
synced 2026-09-09 05:28:43 +00:00
🐛 Fix WASM text selection copy to Windows apps (#11305)
Write text/html alongside text/plain on copy/cut so Windows apps that prefer CF_HTML do not paste the empty contenteditable newline.
This commit is contained in:
parent
8aefa2ddfd
commit
dd6b521bc7
@ -19,6 +19,7 @@
|
|||||||
[app.main.ui.css-cursors :as cur]
|
[app.main.ui.css-cursors :as cur]
|
||||||
[app.render-wasm.api :as wasm.api]
|
[app.render-wasm.api :as wasm.api]
|
||||||
[app.render-wasm.text-editor :as text-editor]
|
[app.render-wasm.text-editor :as text-editor]
|
||||||
|
[app.util.clipboard :as clipboard]
|
||||||
[app.util.dom :as dom]
|
[app.util.dom :as dom]
|
||||||
[app.util.keyboard :as kbd]
|
[app.util.keyboard :as kbd]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
@ -267,8 +268,13 @@
|
|||||||
(when (text-editor/text-editor-has-focus?)
|
(when (text-editor/text-editor-has-focus?)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(when (text-editor/text-editor-has-selection?)
|
(when (text-editor/text-editor-has-selection?)
|
||||||
(let [text (text-editor/text-editor-export-selection)]
|
(let [text (or (text-editor/text-editor-export-selection) "")
|
||||||
(.setData (.-clipboardData event) "text/plain" text))))))
|
html (clipboard/plain-text->html text)
|
||||||
|
data (.-clipboardData event)]
|
||||||
|
;; text/html matters on Windows: many apps prefer CF_HTML, and
|
||||||
|
;; without it they can pick up the empty contenteditable `<br>`.
|
||||||
|
(.setData data "text/plain" text)
|
||||||
|
(.setData data "text/html" html))))))
|
||||||
|
|
||||||
on-cut
|
on-cut
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
@ -276,9 +282,12 @@
|
|||||||
(when (text-editor/text-editor-has-focus?)
|
(when (text-editor/text-editor-has-focus?)
|
||||||
(dom/prevent-default event)
|
(dom/prevent-default event)
|
||||||
(when (text-editor/text-editor-has-selection?)
|
(when (text-editor/text-editor-has-selection?)
|
||||||
(let [text (text-editor/text-editor-export-selection)]
|
(let [text (or (text-editor/text-editor-export-selection) "")
|
||||||
(.setData (.-clipboardData event) "text/plain" (or text ""))
|
html (clipboard/plain-text->html text)
|
||||||
(when (and text (seq text))
|
data (.-clipboardData event)]
|
||||||
|
(.setData data "text/plain" text)
|
||||||
|
(.setData data "text/html" html)
|
||||||
|
(when (seq text)
|
||||||
(text-editor/text-editor-delete-backward)
|
(text-editor/text-editor-delete-backward)
|
||||||
(sync-wasm-text-editor-content!)
|
(sync-wasm-text-editor-content!)
|
||||||
(wasm.api/request-render-preserving-target "text-cut"))))
|
(wasm.api/request-render-preserving-target "text-cut"))))
|
||||||
|
|||||||
@ -22,6 +22,18 @@
|
|||||||
#js {:decodeTransit t/decode-str
|
#js {:decodeTransit t/decode-str
|
||||||
:allowHTMLPaste false})
|
:allowHTMLPaste false})
|
||||||
|
|
||||||
|
(defn plain-text->html
|
||||||
|
"Build a minimal text/html clipboard payload from plain text.
|
||||||
|
|
||||||
|
Windows apps often prefer CF_HTML over CF_UNICODETEXT; writing only
|
||||||
|
text/plain from a contenteditable copy handler can leave them with the
|
||||||
|
editor surface's empty/`<br>` fallback (a lone newline)."
|
||||||
|
[text]
|
||||||
|
(let [escaped (-> (or text "")
|
||||||
|
(dom/escape-html)
|
||||||
|
(str/replace "\n" "<br>"))]
|
||||||
|
(str "<meta charset=\"utf-8\">" escaped)))
|
||||||
|
|
||||||
(defn- from-data-transfer
|
(defn- from-data-transfer
|
||||||
"Get clipboard stream from DataTransfer instance"
|
"Get clipboard stream from DataTransfer instance"
|
||||||
([data-transfer]
|
([data-transfer]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user