mirror of
https://github.com/penpot/penpot.git
synced 2025-03-14 16:51:18 -05:00
🐛 Fix copy paste can produce nested components
This commit is contained in:
parent
33fb979b2c
commit
fc038998d5
3 changed files with 28 additions and 16 deletions
|
@ -388,18 +388,7 @@
|
||||||
|
|
||||||
(defmethod process-change :mov-objects
|
(defmethod process-change :mov-objects
|
||||||
[data {:keys [parent-id shapes index page-id component-id ignore-touched after-shape]}]
|
[data {:keys [parent-id shapes index page-id component-id ignore-touched after-shape]}]
|
||||||
(letfn [(nested-components? [objects shape-id]
|
(letfn [(calculate-invalid-targets [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]
|
|
||||||
(let [reduce-fn #(into %1 (calculate-invalid-targets objects %2))]
|
(let [reduce-fn #(into %1 (calculate-invalid-targets objects %2))]
|
||||||
(->> (get-in objects [shape-id :shapes])
|
(->> (get-in objects [shape-id :shapes])
|
||||||
(reduce reduce-fn #{shape-id}))))
|
(reduce reduce-fn #{shape-id}))))
|
||||||
|
@ -410,7 +399,7 @@
|
||||||
(let [invalid-targets (calculate-invalid-targets objects shape-id)]
|
(let [invalid-targets (calculate-invalid-targets objects shape-id)]
|
||||||
(and (contains? objects shape-id)
|
(and (contains? objects shape-id)
|
||||||
(not (invalid-targets parent-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))))
|
#_(cph/valid-frame-target? objects parent-id shape-id))))
|
||||||
|
|
||||||
(insert-items [prev-shapes index shapes]
|
(insert-items [prev-shapes index shapes]
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[app.common.types.pages-list :as ctpl]
|
[app.common.types.pages-list :as ctpl]
|
||||||
[app.common.types.shape.layout :as ctl]
|
[app.common.types.shape.layout :as ctl]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
|
[clojure.set :as set]
|
||||||
[cuerdas.core :as str]))
|
[cuerdas.core :as str]))
|
||||||
|
|
||||||
(declare reduce-objects)
|
(declare reduce-objects)
|
||||||
|
@ -302,6 +303,19 @@
|
||||||
(ctkl/get-component file id))
|
(ctkl/get-component file id))
|
||||||
(assoc :type type)))
|
(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
|
;; ALGORITHMS & TRANSFORMATIONS FOR SHAPES
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
|
@ -1646,9 +1646,18 @@
|
||||||
tree-root (get-tree-root-shapes paste-objects)
|
tree-root (get-tree-root-shapes paste-objects)
|
||||||
only-one-root-shape? (and
|
only-one-root-shape? (and
|
||||||
(< 1 (count paste-objects))
|
(< 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
|
(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)
|
(selected-frame? state)
|
||||||
|
|
||||||
(if (or (any-same-frame-from-selected? state (keys paste-objects))
|
(if (or (any-same-frame-from-selected? state (keys paste-objects))
|
||||||
|
|
Loading…
Add table
Reference in a new issue