0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-13 00:01:51 -05:00

🐛 Fix copy paste can produce nested components

This commit is contained in:
Pablo Alba 2023-05-31 13:20:32 +02:00 committed by Andrés Moya
parent 33fb979b2c
commit fc038998d5
3 changed files with 28 additions and 16 deletions

View file

@ -388,18 +388,7 @@
(defmethod process-change :mov-objects
[data {:keys [parent-id shapes index page-id component-id ignore-touched after-shape]}]
(letfn [(nested-components? [objects shape-id]
(let [children (cph/get-children-with-self objects shape-id)
xf-get-component-id (keep :component-id)
child-components (into #{} xf-get-component-id children)
parents (cph/get-parents-with-self objects parent-id)
xf-get-main-id (comp (filter :main-instance?)
xf-get-component-id)
parent-components (into #{} xf-get-main-id parents)]
(seq (set/intersection child-components parent-components))))
(calculate-invalid-targets [objects shape-id]
(letfn [(calculate-invalid-targets [objects shape-id]
(let [reduce-fn #(into %1 (calculate-invalid-targets objects %2))]
(->> (get-in objects [shape-id :shapes])
(reduce reduce-fn #{shape-id}))))
@ -410,7 +399,7 @@
(let [invalid-targets (calculate-invalid-targets objects shape-id)]
(and (contains? objects shape-id)
(not (invalid-targets parent-id))
(not (nested-components? objects shape-id))
(not (cph/components-nesting-loop? objects shape-id parent-id))
#_(cph/valid-frame-target? objects parent-id shape-id))))
(insert-items [prev-shapes index shapes]

View file

@ -12,6 +12,7 @@
[app.common.types.pages-list :as ctpl]
[app.common.types.shape.layout :as ctl]
[app.common.uuid :as uuid]
[clojure.set :as set]
[cuerdas.core :as str]))
(declare reduce-objects)
@ -302,6 +303,19 @@
(ctkl/get-component file id))
(assoc :type type)))
(defn components-nesting-loop?
"Check if a nesting loop would be created if the given shape is moved below the given parent"
[objects shape-id parent-id]
(let [children (get-children-with-self objects shape-id)
xf-get-component-id (keep :component-id)
child-components (into #{} xf-get-component-id children)
parents (get-parents-with-self objects parent-id)
xf-get-main-id (comp (filter :main-instance?)
xf-get-component-id)
parent-components (into #{} xf-get-main-id parents)]
(seq (set/intersection child-components parent-components))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ALGORITHMS & TRANSFORMATIONS FOR SHAPES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -1646,9 +1646,18 @@
tree-root (get-tree-root-shapes paste-objects)
only-one-root-shape? (and
(< 1 (count paste-objects))
(= 1 (count tree-root)))]
(= 1 (count tree-root)))
all-objects (merge page-objects paste-objects)
comps-nesting-loop? (not (->> (keys paste-objects)
(map #(cph/components-nesting-loop? all-objects % (:id base)))
(every? nil?)))]
(cond
comps-nesting-loop?
;; Avoid placing a shape as a direct or indirect child of itself,
;; or inside its main component if it's in a copy.
[uuid/zero uuid/zero (gpt/subtract mouse-pos orig-pos)]
(selected-frame? state)
(if (or (any-same-frame-from-selected? state (keys paste-objects))