mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
🐛 Validate pasted shapes where they are pasted
generate-duplicate-changes looked for the instance roots of the copied shapes in the page they were copied from, and mapped them to the new ids. Pasting a main into another main creates a nested copy, but the copy was validated on its own and reported :nested-copy-not-allowed. Shapes copied from inside a component and pasted outside were not validated at all: the unchanged source root was validated instead. Look for the instance roots from the new shapes, in the objects of the changes builder, where they already are in their new place. This fixes three tests in frontend pasting_in_containers_test. AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
e702b44121
commit
743431bd42
@ -3230,11 +3230,13 @@
|
||||
(map #(vector (:old-id %) (-> % :obj :id))))
|
||||
(:redo-changes changes))
|
||||
|
||||
copied-components
|
||||
(ctn/get-all-instance-roots (:objects page) ids)
|
||||
|
||||
;; Look for the instance roots from the new shapes, where they have
|
||||
;; been pasted. A copy pasted inside another component is a nested
|
||||
;; copy, so the root of the enclosing instance is validated instead
|
||||
;; of the copy alone
|
||||
ids-to-validate
|
||||
(map #(get ids-map % %) copied-components)
|
||||
(ctn/get-all-instance-roots (pcb/get-objects changes)
|
||||
(keep ids-map ids))
|
||||
|
||||
changes (if (seq ids-to-validate)
|
||||
(pcb/validate-shapes changes
|
||||
|
||||
@ -819,3 +819,70 @@
|
||||
;; ==== Check
|
||||
(t/is (= 3 (count (:shapes v02'))))
|
||||
(t/is (validates-shapes? changes [v02-id]))))
|
||||
|
||||
(defn- paste-changes
|
||||
"Build the changes of pasting a copy of the shape into the parent, as the
|
||||
workspace does."
|
||||
[file shape-label parent-label]
|
||||
(let [page (thf/current-page file)
|
||||
shape-id (thi/id shape-label)
|
||||
parent-id (thi/id parent-label)
|
||||
objects (update (:objects page) shape-id assoc :parent-id parent-id :frame-id parent-id)]
|
||||
(-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(cll/generate-duplicate-changes objects page #{shape-id} (gpt/point 0 0)
|
||||
{(:id file) file} (:data file) (:id file)))))
|
||||
|
||||
(defn- pasted-id
|
||||
[changes shape-label]
|
||||
(->> (:redo-changes changes)
|
||||
(filter #(and (= :add-obj (:type %))
|
||||
(= (thi/id shape-label) (:old-id %))))
|
||||
first
|
||||
:obj
|
||||
:id))
|
||||
|
||||
(t/deftest test-paste-main-into-main-validates-enclosing-root
|
||||
;; Pasting a main into another main creates a nested copy, that can't be
|
||||
;; validated on its own: the root of the enclosing main is validated
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component :component1 :main1-root :main1-child)
|
||||
(tho/add-simple-component :component2 :main2-root :main2-child))
|
||||
|
||||
;; ==== Action
|
||||
changes (paste-changes file :main2-root :main1-root)
|
||||
file' (thf/apply-changes file changes)
|
||||
copy' (ths/get-shape-by-id file' (pasted-id changes :main2-root))]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (= (thi/id :main1-root) (:parent-id copy')))
|
||||
(t/is (not (ctk/instance-root? copy')))
|
||||
(t/is (validates-shapes? changes [(thi/id :main1-root)]))))
|
||||
|
||||
(t/deftest test-paste-copy-at-root-validates-new-copy
|
||||
(let [;; ==== Setup
|
||||
file (-> (thf/sample-file :file1)
|
||||
(tho/add-simple-component-with-copy :component1
|
||||
:main1-root
|
||||
:main1-child
|
||||
:copy1-root))
|
||||
page (thf/current-page file)
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(pcb/with-page-id (:id page))
|
||||
(pcb/with-library-data (:data file))
|
||||
(pcb/with-objects (:objects page))
|
||||
(cll/generate-duplicate-changes (:objects page) page #{(thi/id :copy1-root)}
|
||||
(gpt/point 0 0)
|
||||
{(:id file) file} (:data file) (:id file)))
|
||||
new-id (pasted-id changes :copy1-root)
|
||||
file' (thf/apply-changes file changes)]
|
||||
|
||||
;; ==== Check
|
||||
(t/is (ctk/instance-root? (ths/get-shape-by-id file' new-id)))
|
||||
(t/is (validates-shapes? changes [new-id]))))
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user