From 16a1fd14e5d6b139b384419eb0045ce8159819c8 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 7 Jul 2025 09:03:35 +0200 Subject: [PATCH] :bug: Fix media translation on text nodes on paste (#6845) Fix incorrect media translation on paste text with fill images --- CHANGES.md | 1 + common/src/app/common/text.cljc | 13 ------ .../app/main/data/workspace/clipboard.cljs | 44 ++++++++----------- 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8b300a48dc..e13fb4fb16 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -63,6 +63,7 @@ on-premises instances** that want to keep up to date. - Fix entering long project name [Taiga #11417](https://tree.taiga.io/project/penpot/issue/11417) - Fix slow color picker [Taiga #11019](https://tree.taiga.io/project/penpot/issue/11019) - Fix tooltip position after click [Taiga #11405](https://tree.taiga.io/project/penpot/issue/11405) +- Fix incorrect media translation on paste text with fill images [Github #6845](https://github.com/penpot/penpot/pull/6845) ## 2.7.2 diff --git a/common/src/app/common/text.cljc b/common/src/app/common/text.cljc index 9e635f6a03..469fda6eb3 100644 --- a/common/src/app/common/text.cljc +++ b/common/src/app/common/text.cljc @@ -170,19 +170,6 @@ item)) root))) -(defn xform-nodes - "The same as transform but instead of receiving a funcion, receives - a transducer." - [xf root] - (let [rf (fn [_ v] v)] - (walk/postwalk - (fn [item] - (let [rf (xf rf)] - (if (is-node? item) - (d/nilv (rf nil item) item) - item))) - root))) - (defn update-text-content [shape pred-fn update-fn attrs] (let [update-attrs-fn #(update-fn % attrs) diff --git a/frontend/src/app/main/data/workspace/clipboard.cljs b/frontend/src/app/main/data/workspace/clipboard.cljs index 39efb0e616..1a40e0ed3b 100644 --- a/frontend/src/app/main/data/workspace/clipboard.cljs +++ b/frontend/src/app/main/data/workspace/clipboard.cljs @@ -673,41 +673,35 @@ (defn paste-shapes [{in-viewport? :in-viewport :as pdata}] - (letfn [(translate-media [mdata media-idx attr-path] - (let [id (-> (get-in mdata attr-path) - (:id)) + (letfn [(translate-media [mdata media-idx attr] + (let [id (-> (get mdata attr) :id) mobj (get media-idx id)] (if mobj - (if (empty? attr-path) - (assoc mdata :id (:id mobj)) - (update-in mdata attr-path assoc :id (:id mobj))) + (update mdata attr assoc :id (:id mobj)) mdata))) (add-obj? [chg] (= (:type chg) :add-obj)) + (process-rchange-shape [obj media-idx] + (let [translate-fill-image #(translate-media % media-idx :fill-image) + translate-stroke-image #(translate-media % media-idx :stroke-image) + translate-fills #(mapv translate-fill-image %) + translate-strokes #(mapv translate-stroke-image %) + process-text-node #(d/update-when % :fills translate-fills)] + + (-> obj + (update :fills translate-fills) + (update :strokes translate-strokes) + (d/update-when :content #(txt/transform-nodes process-text-node %)) + (d/update-when :position-data #(mapv process-text-node %))))) + ;; Analyze the rchange and replace staled media and ;; references to the new uploaded media-objects. (process-rchange [media-idx change] - (let [;; Texts can have different fills for pieces of the text - tr-fill-xf (map #(translate-media % media-idx [:fill-image])) - tr-stroke-xf (map #(translate-media % media-idx [:stroke-image]))] - (if (add-obj? change) - (update change :obj (fn [obj] - (-> obj - (update :fills #(into [] tr-fill-xf %)) - (update :strokes #(into [] tr-stroke-xf %)) - (d/update-when :metadata translate-media media-idx []) - (d/update-when :fill-image translate-media media-idx []) - (d/update-when :content - (fn [content] - (txt/xform-nodes tr-fill-xf content))) - (d/update-when :position-data - (fn [position-data] - (mapv (fn [pos-data] - (update pos-data :fills #(into [] tr-fill-xf %))) - position-data)))))) - change))) + (if (add-obj? change) + (update change :obj process-rchange-shape media-idx) + change)) (calculate-paste-position [state pobjects selected position] (let [page-objects (dsh/lookup-page-objects state)