mirror of
https://github.com/penpot/penpot.git
synced 2025-05-10 22:16:38 +02:00
Merge pull request #3245 from penpot/hiru-fix-nesting-loop
🐛 Avoid infinite loop nesting copies inside components
This commit is contained in:
commit
610e34e05b
2 changed files with 24 additions and 7 deletions
|
@ -74,8 +74,8 @@
|
||||||
[:frame-id {:optional true} ::sm/uuid]
|
[:frame-id {:optional true} ::sm/uuid]
|
||||||
[:parent-id {:optional true} ::sm/uuid]
|
[:parent-id {:optional true} ::sm/uuid]
|
||||||
[:index {:optional true} [:maybe :int]]
|
[:index {:optional true} [:maybe :int]]
|
||||||
[:ignore-touched {:optional true} :boolean]
|
[:ignore-touched {:optional true} :boolean]]]
|
||||||
]]
|
|
||||||
|
|
||||||
[:mod-obj
|
[:mod-obj
|
||||||
[:map {:title "ModObjChange"}
|
[:map {:title "ModObjChange"}
|
||||||
|
@ -214,9 +214,9 @@
|
||||||
[:del-typography
|
[:del-typography
|
||||||
[:map {:title "DelTypogrphyChange"}
|
[:map {:title "DelTypogrphyChange"}
|
||||||
[:type [:= :del-typography]]
|
[:type [:= :del-typography]]
|
||||||
[:id ::sm/uuid]]]
|
[:id ::sm/uuid]]]]])
|
||||||
|
|
||||||
|
|
||||||
]])
|
|
||||||
|
|
||||||
(def change?
|
(def change?
|
||||||
(sm/pred-fn ::change))
|
(sm/pred-fn ::change))
|
||||||
|
@ -388,15 +388,29 @@
|
||||||
|
|
||||||
(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 [(calculate-invalid-targets [objects shape-id]
|
(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]
|
||||||
(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}))))
|
||||||
|
|
||||||
|
;; Avoid placing a shape as a direct or indirect child of itself,
|
||||||
|
;; or inside its main component if it's in a copy.
|
||||||
(is-valid-move? [objects shape-id]
|
(is-valid-move? [objects shape-id]
|
||||||
(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))
|
||||||
#_(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]
|
||||||
|
@ -431,14 +445,12 @@
|
||||||
component? (and (:shape-ref obj)
|
component? (and (:shape-ref obj)
|
||||||
(= (:type obj) :group)
|
(= (:type obj) :group)
|
||||||
(not ignore-touched))]
|
(not ignore-touched))]
|
||||||
|
|
||||||
(-> objects
|
(-> objects
|
||||||
(d/update-in-when [pid :shapes] d/without-obj sid)
|
(d/update-in-when [pid :shapes] d/without-obj sid)
|
||||||
(d/update-in-when [pid :shapes] d/vec-without-nils)
|
(d/update-in-when [pid :shapes] d/vec-without-nils)
|
||||||
(cond-> component? (d/update-when pid #(-> %
|
(cond-> component? (d/update-when pid #(-> %
|
||||||
(update :touched cph/set-touched-group :shapes-group)
|
(update :touched cph/set-touched-group :shapes-group)
|
||||||
(dissoc :remote-synced?)))))))))
|
(dissoc :remote-synced?)))))))))
|
||||||
|
|
||||||
(update-parent-id [objects id]
|
(update-parent-id [objects id]
|
||||||
(-> objects
|
(-> objects
|
||||||
(d/update-when id assoc :parent-id parent-id)))
|
(d/update-when id assoc :parent-id parent-id)))
|
||||||
|
|
|
@ -125,6 +125,11 @@
|
||||||
(recur (conj result parent-id) parent-id)
|
(recur (conj result parent-id) parent-id)
|
||||||
result))))
|
result))))
|
||||||
|
|
||||||
|
(defn get-parents-with-self
|
||||||
|
[objects id]
|
||||||
|
(let [lookup (d/getf objects)]
|
||||||
|
(into [(lookup id)] (map lookup) (get-parent-ids objects id))))
|
||||||
|
|
||||||
(defn hidden-parent?
|
(defn hidden-parent?
|
||||||
"Checks the parent for the hidden property"
|
"Checks the parent for the hidden property"
|
||||||
[objects shape-id]
|
[objects shape-id]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue