From 579de6558a6a987d0fa94e94a62ec4ba3c44283e Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Tue, 21 Oct 2025 09:35:17 +0200 Subject: [PATCH] :bug: Fix on copy instance inside a components chain touched are missing --- CHANGES.md | 1 + .../app/main/data/workspace/clipboard.cljs | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cab10c3bc7..785f111acb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,6 +15,7 @@ - Fix pan cursor not disabling viewport guides [Github #6985](https://github.com/penpot/penpot/issues/6985) - Fix viewport resize on locked shapes [Taiga #11974](https://tree.taiga.io/project/penpot/issue/11974) - Fix nested variant in a component doesn't keep inherited overrides [Taiga #12299](https://tree.taiga.io/project/penpot/issue/12299) +- Fix on copy instance inside a components chain touched are missing [Taiga #12371](https://tree.taiga.io/project/penpot/issue/12371) ## 2.11.0 (Unreleased) diff --git a/frontend/src/app/main/data/workspace/clipboard.cljs b/frontend/src/app/main/data/workspace/clipboard.cljs index be32317596..2968b37834 100644 --- a/frontend/src/app/main/data/workspace/clipboard.cljs +++ b/frontend/src/app/main/data/workspace/clipboard.cljs @@ -59,6 +59,31 @@ [potok.v2.core :as ptk] [promesa.core :as p])) + +(defn- get-ref-chain-until-target-ref + "Returns a vector with the shape ref chain until target-ref, including itself" + [container libraries shape target-ref] + (loop [chain [shape] + current shape] + (if (= current target-ref) + chain + (if-let [ref (ctf/find-ref-shape nil container libraries current :with-context? true)] + (recur (conj chain ref) ref) + chain)))) + +(defn- get-touched-from-ref-chain-until-target-ref + "Returns a set with the :touched of all the items on the shape + ref chain until target-ref, including itself" + [container libraries shape target-ref] + (let [chain (when target-ref (get-ref-chain-until-target-ref container libraries shape target-ref)) + more-touched (->> chain + (map :touched) + (remove nil?) + (apply set/union) + (remove ctc/swap-slot?) + set)] + (set/union (or (:touched shape) #{}) more-touched))) + (defn copy-selected [] (letfn [(sort-selected [state data] @@ -164,10 +189,13 @@ objects)) (advance-shape [file libraries page level-delta objects shape] - (let [new-shape-ref (ctf/advance-shape-ref file page libraries shape level-delta {:include-deleted? true})] + (let [new-shape-ref (ctf/advance-shape-ref file page libraries shape level-delta {:include-deleted? true}) + container (ctn/make-container page :page) + new-touched (get-touched-from-ref-chain-until-target-ref container libraries shape new-shape-ref)] (cond-> objects (and (some? new-shape-ref) (not= new-shape-ref (:shape-ref shape))) - (assoc-in [(:id shape) :shape-ref] new-shape-ref)))) + (-> (assoc-in [(:id shape) :shape-ref] new-shape-ref) + (assoc-in [(:id shape) :touched] new-touched))))) (on-copy-error [error] (js/console.error "clipboard blocked:" error)