mirror of
https://github.com/penpot/penpot.git
synced 2026-11-12 13:00:37 +00:00
🐛 Keep the swap slot when duplicating a swapped nested copy
This commit is contained in:
parent
54b1eb5d5f
commit
3eebe92606
@ -3165,6 +3165,7 @@
|
||||
is-component-main? (ctk/main-instance? obj)
|
||||
subinstance-head? (ctk/subinstance-head? obj)
|
||||
instance-root? (ctk/instance-root? obj)
|
||||
parent-not-in-copy (not (ctk/in-component-copy? parent))
|
||||
|
||||
into-component? (and duplicating-component?
|
||||
(ctn/in-any-component? objects parent))
|
||||
@ -3174,6 +3175,8 @@
|
||||
(ctn/get-nesting-level-delta objects obj parent))
|
||||
new-shape-ref (ctf/advance-shape-ref nil page libraries obj level-delta {:include-deleted? true})
|
||||
|
||||
|
||||
|
||||
regenerate-component
|
||||
(fn [changes shape]
|
||||
(let [[_ changes] (generate-add-component-changes changes shape objects file-id (:id page) variant-props)]
|
||||
@ -3188,7 +3191,8 @@
|
||||
|
||||
(cond-> (and (not instance-root?)
|
||||
subinstance-head?
|
||||
remove-swap-slot?)
|
||||
remove-swap-slot?
|
||||
parent-not-in-copy)
|
||||
(ctk/remove-swap-slot))
|
||||
|
||||
(dissoc :shapes
|
||||
|
||||
@ -196,7 +196,7 @@
|
||||
;; Calculate how many parent heads share in common the original
|
||||
;; shape and the new parent.
|
||||
pairs (map vector orig-heads dest-heads)
|
||||
common-count (count (take-while (fn [a b] (= a b)) pairs))]
|
||||
common-count (count (take-while (fn [[a b]] (= a b)) pairs))]
|
||||
|
||||
(- (count orig-heads) common-count)))
|
||||
|
||||
|
||||
@ -567,3 +567,62 @@
|
||||
;; blue2' has not swap-id after move
|
||||
(t/is (some? blue2'))
|
||||
(t/is (nil? (ctk/get-swap-slot blue2')))))
|
||||
|
||||
(defn- setup-nested-swap-file
|
||||
[]
|
||||
;; {:frame-icon-a} [:name Frame1] # [Component :icon-a]
|
||||
;; {:frame-icon-b} [:name Frame1] # [Component :icon-b]
|
||||
;; {:frame-card} [:name Frame1] # [Component :card]
|
||||
;; :frame-inner [:name Frame1]
|
||||
;; :icon-copy [:name Frame1] @--> :frame-icon-a
|
||||
;; :card-copy [:name Frame1] @--> :frame-card
|
||||
;; :inner-copy [:name Frame1] @--> :frame-inner
|
||||
;; :icon-in-card-copy [:name Frame1] @--> :frame-icon-a
|
||||
;; swapped to :icon-b, it becomes
|
||||
;; :icon-b-copy [:name Frame1, swap-slot] @--> :frame-icon-b
|
||||
(-> (thf/sample-file :file1)
|
||||
(tho/add-frame :frame-icon-a)
|
||||
(thc/make-component :icon-a :frame-icon-a)
|
||||
(tho/add-frame :frame-icon-b)
|
||||
(thc/make-component :icon-b :frame-icon-b)
|
||||
(tho/add-frame :frame-card)
|
||||
(thc/make-component :card :frame-card)
|
||||
(tho/add-frame :frame-inner :parent-label :frame-card)
|
||||
(thc/instantiate-component :icon-a :icon-copy :parent-label :frame-inner)
|
||||
(thc/instantiate-component :card :card-copy
|
||||
:children-labels [:inner-copy :icon-in-card-copy])
|
||||
(thc/component-swap :icon-in-card-copy :icon-b :icon-b-copy)))
|
||||
|
||||
(t/deftest test-keep-swap-slot-duplicating-swapped-nested-copy-inside-copy
|
||||
(let [;; ==== Setup
|
||||
file (setup-nested-swap-file)
|
||||
|
||||
page (thf/current-page file)
|
||||
icon-b-copy (ths/get-shape file :icon-b-copy)
|
||||
|
||||
;; ==== Action
|
||||
changes (-> (pcb/empty-changes nil)
|
||||
(cll/generate-duplicate-changes (:objects page) ;; objects
|
||||
page ;; page
|
||||
#{(:id icon-b-copy)} ;; ids
|
||||
(gpt/point 0 0) ;; delta
|
||||
{(:id file) file} ;; libraries
|
||||
(:data file) ;; library-data
|
||||
(:id file)) ;; file-id
|
||||
(cll/generate-duplicate-changes-update-indices (:objects page) ;; objects
|
||||
#{(:id icon-b-copy)})) ;; ids
|
||||
|
||||
file' (thf/apply-changes file changes)
|
||||
|
||||
;; ==== Get
|
||||
page' (thf/current-page file')
|
||||
duplicated-icon-b' (find-duplicated-shape icon-b-copy page')]
|
||||
|
||||
;; ==== Check
|
||||
|
||||
;; icon-b-copy has swap-slot
|
||||
(t/is (some? (ctk/get-swap-slot icon-b-copy)))
|
||||
|
||||
;; duplicated icon-b copy keeps its swap-slot
|
||||
(t/is (some? duplicated-icon-b'))
|
||||
(t/is (some? (ctk/get-swap-slot duplicated-icon-b')))))
|
||||
|
||||
@ -291,3 +291,42 @@
|
||||
(t/testing "two ordinary outside shapes are both kept"
|
||||
(t/is (= [outside-id outside-2-id]
|
||||
(vec (ctc/ids-for-structure-op objects [outside-id outside-2-id])))))))
|
||||
|
||||
(t/deftest get-nesting-level-delta
|
||||
(let [page-id uuid/zero
|
||||
head-id (uuid/next)
|
||||
frame-id (uuid/next)
|
||||
sub-id (uuid/next)
|
||||
head-2-id (uuid/next)
|
||||
plain-id (uuid/next)
|
||||
;; copy head with a plain frame and a nested copy head inside
|
||||
head (make-shape head-id
|
||||
:parent-id page-id
|
||||
:type :frame
|
||||
:component-id (uuid/next)
|
||||
:component-root true
|
||||
:shape-ref (uuid/next))
|
||||
frame (make-shape frame-id :parent-id head-id :type :frame :shape-ref (uuid/next))
|
||||
sub (make-shape sub-id
|
||||
:parent-id frame-id
|
||||
:type :frame
|
||||
:component-id (uuid/next)
|
||||
:shape-ref (uuid/next))
|
||||
head-2 (make-shape head-2-id
|
||||
:parent-id page-id
|
||||
:type :frame
|
||||
:component-id (uuid/next)
|
||||
:component-root true
|
||||
:shape-ref (uuid/next))
|
||||
plain (make-shape plain-id :parent-id page-id)
|
||||
root (root-shape)
|
||||
objects (objects-map root head frame sub head-2 plain)]
|
||||
(t/testing "shape stays under the same copy head"
|
||||
(t/is (= 0 (ctc/get-nesting-level-delta objects sub frame))))
|
||||
(t/testing "shape leaves its copy head to the page"
|
||||
(t/is (= 1 (ctc/get-nesting-level-delta objects sub root))))
|
||||
(t/testing "shape moves to a different copy head"
|
||||
(t/is (= 1 (ctc/get-nesting-level-delta objects sub head-2))))
|
||||
(t/testing "shape outside any copy head goes inside one"
|
||||
(t/is (= 0 (ctc/get-nesting-level-delta objects plain frame))))))
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user