mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Remove the empty override field after clearing a swap
When removing the last swap group, drop touched instead of retaining an empty set. A main clone then uses the same representation as set-touched; a later move and undo can restore its exact prior state (F156). The unit and move regressions fail before the change. The swap suite and original shrunk program pass 48 tests and 184 assertions. Common lint and format pass. Benchmark ratios: mains 0.49/0.56/0.79; levels 0.66; chain 0.82; library 0.78; many shapes 0.92; switch 1.02, no regression flags. AI-assisted-by: GPT-6
This commit is contained in:
parent
980c71b645
commit
bc4edefd81
@ -61,3 +61,8 @@ A variant container is a frame with `:is-variant-container true`. Its children a
|
||||
Predicates are broad: `ctk/is-variant?` checks `:variant-id` and applies to both variant master shapes and component rows; `ctk/is-variant-container?` checks the container shape flag.
|
||||
|
||||
Moving/dropping a shape into a variant container through the move-to-frame path can auto-convert it into a variant via `generate-make-shapes-variant`, which may duplicate the underlying component. Treat drag/drop into variant containers as a component/variant operation, not a plain reparent.
|
||||
|
||||
- `ctk/remove-swap-group` removes `:touched` when it removes the final group.
|
||||
New main clones must use the same empty-state representation as
|
||||
`process-operation :set-touched`; otherwise a later move+undo changes
|
||||
`:touched #{}` to a missing field and cannot restore the exact state (F156).
|
||||
|
||||
@ -274,9 +274,12 @@
|
||||
(defn remove-swap-group
|
||||
"Make the shape not swapped."
|
||||
[shape]
|
||||
(cond-> shape
|
||||
(swapped? shape)
|
||||
(update :touched disj :swap-group)))
|
||||
(if (swapped? shape)
|
||||
(let [touched (disj (:touched shape) :swap-group)]
|
||||
(if (seq touched)
|
||||
(assoc shape :touched touched)
|
||||
(dissoc shape :touched)))
|
||||
shape))
|
||||
|
||||
(defn get-deleted-component-root
|
||||
[component]
|
||||
|
||||
@ -805,3 +805,19 @@
|
||||
head (tm/resolve-shape swapped :copy-star)]
|
||||
(t/is (mth/close? 45 (:rotation head) 0.001))
|
||||
(t/is (= #{:swap-group} (:touched head)))))
|
||||
|
||||
(t/deftest removing-the-last-swap-group-leaves-no-empty-override-field
|
||||
(let [shape {:touched #{:swap-group}}]
|
||||
(t/is (not (contains? (ctk/remove-swap-group shape) :touched)))
|
||||
(t/is (= #{:geometry-group}
|
||||
(:touched (ctk/remove-swap-group (assoc shape :touched #{:swap-group :geometry-group})))))))
|
||||
|
||||
(t/deftest moving-a-swapped-subtree-pushed-into-a-main-undoes-exactly
|
||||
(let [updated (-> (tm/make-situation (setup))
|
||||
(r/step (n/update-main :copy)) r/settle)
|
||||
file (tm/file updated)
|
||||
head (tm/shape-by-id updated (:shape-ref (tm/resolve-shape updated :copy-star)))
|
||||
moved (-> updated (r/step (n/nest-copy (constantly (:id head)) :star-main)) r/settle)
|
||||
undone (r/step moved (n/undo))]
|
||||
(t/is (nil? (:touched head)))
|
||||
(t/is (= (thn/normalize-file file) (thn/normalize-file (tm/file undone))))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user