mirror of
https://github.com/penpot/penpot.git
synced 2026-03-14 14:27:11 +00:00
Merge pull request #8580 from penpot/niwinz-staging-fix-paste-issue
🐛 Fix crash when pasting non-map transit clipboard data
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
- Fix 'not ISeqable' error when entering float values in layout item and opacity inputs [Github #8569](https://github.com/penpot/penpot/pull/8569)
|
||||
- Fix crash in select component when options vector is empty [Github #8578](https://github.com/penpot/penpot/pull/8578)
|
||||
- Fix scroll on colorpicker [Taiga #13623](https://tree.taiga.io/project/penpot/issue/13623)
|
||||
- Fix crash when pasting non-map transit clipboard data [Github #8580](https://github.com/penpot/penpot/pull/8580)
|
||||
|
||||
## 2.13.3
|
||||
|
||||
|
||||
@@ -258,33 +258,39 @@
|
||||
#js {:decodeTransit t/decode-str
|
||||
:allowHTMLPaste (features/active-feature? @st/state "text-editor/v2-html-paste")})
|
||||
|
||||
(defn create-paste-from-blob
|
||||
(defn- create-paste-from-blob
|
||||
[in-viewport?]
|
||||
(fn [blob]
|
||||
(let [type (.-type blob)
|
||||
result (cond
|
||||
(= type "image/svg+xml")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-svg-text))
|
||||
(let [type (.-type blob)]
|
||||
(cond
|
||||
(= type "image/svg+xml")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-svg-text))
|
||||
|
||||
(some #(= type %) clipboard/image-types)
|
||||
(rx/of (paste-image blob))
|
||||
(some #(= type %) clipboard/image-types)
|
||||
(rx/of (paste-image blob))
|
||||
|
||||
(= type "text/html")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-html-text))
|
||||
(= type "text/html")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-html-text))
|
||||
|
||||
(= type "application/transit+json")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map (fn [text]
|
||||
(let [transit-data (t/decode-str text)]
|
||||
(assoc transit-data :in-viewport in-viewport?))))
|
||||
(rx/map paste-transit-shapes))
|
||||
(= type "application/transit+json")
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map t/decode-str)
|
||||
(rx/filter map?)
|
||||
(rx/map
|
||||
(fn [pdata]
|
||||
(assoc pdata :in-viewport in-viewport?)))
|
||||
(rx/mapcat
|
||||
(fn [pdata]
|
||||
(case (:type pdata)
|
||||
:copied-props (rx/of (paste-transit-props pdata))
|
||||
:copied-shapes (rx/of (paste-transit-shapes pdata))
|
||||
(rx/empty)))))
|
||||
|
||||
:else
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-text)))]
|
||||
result)))
|
||||
:else
|
||||
(->> (rx/from (.text blob))
|
||||
(rx/map paste-text))))))
|
||||
|
||||
(def default-paste-from-blob (create-paste-from-blob false))
|
||||
|
||||
|
||||
@@ -30,6 +30,15 @@ const exclusiveTypes = [
|
||||
* @property {boolean} [allowHTMLPaste]
|
||||
*/
|
||||
|
||||
const looksLikeJSON = (str) => {
|
||||
if (typeof str !== 'string') return false;
|
||||
const trimmed = str.trim();
|
||||
return (
|
||||
(trimmed.startsWith('{') && trimmed.endsWith('}')) ||
|
||||
(trimmed.startsWith('[') && trimmed.endsWith(']'))
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} text
|
||||
@@ -39,13 +48,14 @@ const exclusiveTypes = [
|
||||
*/
|
||||
function parseText(text, options) {
|
||||
options = options || {};
|
||||
|
||||
const decodeTransit = options["decodeTransit"];
|
||||
if (decodeTransit) {
|
||||
if (decodeTransit && looksLikeJSON(text)) {
|
||||
try {
|
||||
decodeTransit(text);
|
||||
return new Blob([text], { type: "application/transit+json" });
|
||||
} catch (_error) {
|
||||
// NOOP
|
||||
return new Blob([text], { type: "text/plain" });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user