mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Carry variant overrides through deleted near mains
Copies still use stored main data after its component is deleted. Follow that data both when collecting inherited groups and when matching variant children, so a switch keeps inherited size, orientation and child fills. Portable live/deleted controls fail four assertions before the fix and pass all 16 afterward, including repeat sync and exact undo. Library seed 712 case 1462 and its 12-step shrink both pass. Focused regression and golden checks pass 148 tests, 2593 assertions; goldens are unchanged. Live WASM verifies height 80, rotation 45, child fill, groups, undo/redo and later main opacity propagation. Component benchmark ratios: mains 0.51/0.58/0.56; levels 0.50; chain 0.51; library 0.59; many shapes 0.48; variant switch 0.71. All worlds pass the unchanged baseline gate. AI-assisted-by: GPT-6
This commit is contained in:
parent
cfb800620c
commit
e0188af747
@ -53,3 +53,8 @@ After carrying geometry, the switch syncs its new subtree once from the
|
||||
updated builder objects. Untouched children must follow a retained root
|
||||
size through constraints; copying only root attrs leaves them in the old
|
||||
frame (F162). The direct sync keeps carried groups and child swaps.
|
||||
|
||||
Variant carry must collect groups and match children through deleted near
|
||||
mains too (F180). Copies keep those values after deletion. Both the content
|
||||
ref-chain walk and find-shape-ref-child-of include deleted component data;
|
||||
otherwise a switch loses inherited size, rotation groups and child fills.
|
||||
|
||||
@ -298,6 +298,7 @@
|
||||
It will return the shape or nil if it doesn't found any"
|
||||
[container libraries shape parent-id]
|
||||
(let [ref-shape (ctf/find-ref-shape nil container libraries shape
|
||||
:include-deleted? true
|
||||
:with-context? true)
|
||||
|
||||
ref-shape-container (when ref-shape (:container (meta ref-shape)))
|
||||
|
||||
@ -1266,7 +1266,8 @@
|
||||
container container]
|
||||
(if (= (:id current) target-ref)
|
||||
chain
|
||||
(if-let [ref (find-content-ref-shape nil container libraries current :with-context? true)]
|
||||
(if-let [ref (find-content-ref-shape nil container libraries current
|
||||
:include-deleted? true :with-context? true)]
|
||||
(recur (conj chain ref) ref (:container (meta ref)))
|
||||
chain))))
|
||||
|
||||
|
||||
@ -31,6 +31,41 @@
|
||||
|
||||
(t/use-fixtures :each thi/test-fixture)
|
||||
|
||||
(t/deftest switch-keeps-overrides-inherited-through-a-deleted-near-main
|
||||
(doseq [deleted? [false true]]
|
||||
(let [file (-> (thf/sample-file :file)
|
||||
(thv/add-variant :variants :a :main-a :b :main-b
|
||||
:variant1-params {:width 100 :height 100}
|
||||
:variant2-params {:width 100 :height 100})
|
||||
(ths/add-sample-shape :rect-a :parent-label :main-a :width 20 :height 20)
|
||||
(ths/add-sample-shape :rect-b :parent-label :main-b :width 20 :height 20)
|
||||
(tho/add-frame :outer {:width 200 :height 200})
|
||||
(thc/instantiate-component :a :near :parent-label :outer
|
||||
:children-labels [:near-child])
|
||||
(thc/make-component :outer-component :outer)
|
||||
(thc/instantiate-component :outer-component :copy
|
||||
:children-labels [:copy-near :copy-child]))
|
||||
edited (-> (tm/make-situation file)
|
||||
(r/step (n/change-height :near 80)) r/settle
|
||||
(r/step (n/rotate :near 45)) r/settle
|
||||
(r/step (n/change-property :near-child :fills "#00ff00")) r/settle)
|
||||
before (cond-> edited deleted? (r/step (n/delete-component :outer)))
|
||||
switched (-> before (r/step (n/switch-variant :copy-near "Value2")) r/settle)
|
||||
head (tm/resolve-shape switched :copy-near)
|
||||
child (tm/shape-by-id switched (first (:shapes head)))
|
||||
file (tm/file switched)
|
||||
full (:file (r/sync-cascade file {} (keys (get-in file [:data :components]))))]
|
||||
(t/is (empty? (:touched (tm/resolve-shape before :copy-near))))
|
||||
(t/is (mth/close? 80 (:height head) 0.001))
|
||||
(t/is (mth/close? 45 (:rotation head) 0.001))
|
||||
(t/is (= #{:swap-group :geometry-group} (:touched head)))
|
||||
(t/is (= "#00ff00" (get-in child [:fills 0 :fill-color])))
|
||||
(t/is (= #{:fill-group} (:touched child)))
|
||||
(t/is (gsh/close-attrs? :points (:points head)
|
||||
(:points (ths/get-shape-by-id full (:id head))) 0.001))
|
||||
(t/is (= (:data (tm/file before))
|
||||
(:data (tm/file (r/step switched (n/undo)))))))))
|
||||
|
||||
(t/deftest switching-an-untouched-rotated-copy-authors-its-retained-orientation
|
||||
(let [file (-> (thf/sample-file :file)
|
||||
(thv/add-variant :variant :c01 :m01 :c02 :m02
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user