mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
✨ Pin that a deleted component keeps passing changes on
When a component nested in others is deleted (inner in mid in outer, mid deleted), a change to inner still reaches mid's stored shapes, mid's copies, outer and outer's copies, and restoring mid brings back an up-to-date main. Keep this behavior: outer is a live component, and its users cannot see a deleted mid between it and inner. Extend the deleted-component propagation test with a copy of the deleted component and its restore, and reword the contract, which said copies of a deleted component do not sync. AI-assisted-by: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
c7a40e525c
commit
78ef2dffe6
@ -31,7 +31,7 @@ Intended semantics of copies, `:touched` and component sync. This is the spec: w
|
||||
- Duplicate a copy: the new subtree keeps the source's values and touched; if its nesting level changes, touched is inherited as in detach. Paste and move out of a copy follow the same rule.
|
||||
- Swap without keep-touched: the new subtree is clean and keeps `swap-keep-attrs` values; the new head keeps the old shape's id. Inside a copy it keeps the old `:shape-ref` and gets `:swap-group` (none when the new component is the near main's); inside a main it is a plain nested copy.
|
||||
- Variant switch with keep-touched: an attr is carried from the old copy only when its group is touched and the old and new mains hold the same value for it. Resulting touched = groups of carried attrs (+ `:swap-group` when the head is inside a copy). A value equal to the new main is not carried and not touched.
|
||||
- Delete component: copies keep their data and do not sync. Restore brings sync back.
|
||||
- Delete component: copies keep their data. The deleted main cannot be edited, so it starts no sync, but changes from components nested in it still pass through: sync updates its stored shapes (`:objects` of the deleted component), its copies, and the components that nest it. Restore brings back an up-to-date main.
|
||||
- Undo/redo: restores the exact prior state, `:touched` and `:remote-synced` included, of the op and the sync it caused together (same undo group, one step). Undo never needs a re-sync.
|
||||
|
||||
## Geometry ownership
|
||||
|
||||
@ -89,17 +89,37 @@
|
||||
|
||||
(tho/add-frame :frame-comp-6)
|
||||
(thc/instantiate-component :comp-5 :copy-comp-5 :parent-label :frame-comp-6 :children-labels [:comp-4-comp-5])
|
||||
(thc/make-component :comp-6 :frame-comp-6)))
|
||||
(thc/make-component :comp-6 :frame-comp-6)
|
||||
|
||||
(thc/instantiate-component :comp-5 :loose-copy-comp-5)))
|
||||
|
||||
(propagate-all-component-changes [file]
|
||||
(-> file
|
||||
(tho/propagate-component-changes :comp-4)
|
||||
(tho/propagate-component-changes :comp-5)))
|
||||
|
||||
(stored-fill-color [file]
|
||||
(let [component (thc/get-component file :comp-5 :include-deleted? true)]
|
||||
(when (:deleted component)
|
||||
(->> (vals (:objects component))
|
||||
(some #(when (= :rect (:type %))
|
||||
(-> % :fills first :fill-color)))))))
|
||||
|
||||
(fill-colors [file]
|
||||
[(tho/bottom-fill-color file :frame-comp-4)
|
||||
(tho/bottom-fill-color file :frame-comp-5)
|
||||
(tho/bottom-fill-color file :frame-comp-6)])
|
||||
(tho/bottom-fill-color file :frame-comp-6)
|
||||
(tho/bottom-fill-color file :loose-copy-comp-5)])
|
||||
|
||||
(restore-comp-5 [file]
|
||||
(let [page (thf/current-page file)]
|
||||
(thf/apply-changes file
|
||||
(cll/generate-restore-component (pcb/empty-changes)
|
||||
(:data file)
|
||||
(thi/id :comp-5)
|
||||
(:id file)
|
||||
page
|
||||
(:objects page)))))
|
||||
|
||||
(validate [file validator]
|
||||
(validator file)
|
||||
@ -108,9 +128,15 @@
|
||||
(-> (setup)
|
||||
;; Delete Comp5.
|
||||
(tho/delete-shape :frame-comp-5)
|
||||
(validate #(t/is (= (fill-colors %) ["#b1b2b5" nil "#b1b2b5"])))
|
||||
(validate #(t/is (= (fill-colors %) ["#b1b2b5" nil "#b1b2b5" "#b1b2b5"])))
|
||||
|
||||
;; Change the color of Comp4
|
||||
;; Desired result: Comp6 change color
|
||||
;; Desired result: the deleted Comp5 keeps passing the change on, to
|
||||
;; its stored main, its copy and Comp6
|
||||
(tho/update-bottom-color :frame-comp-4 "#FF0000" :propagate-fn propagate-all-component-changes)
|
||||
(validate #(t/is (= (fill-colors %) ["#FF0000" nil "#FF0000"]))))))
|
||||
(validate #(t/is (= (fill-colors %) ["#FF0000" nil "#FF0000" "#FF0000"])))
|
||||
(validate #(t/is (= (stored-fill-color %) "#FF0000")))
|
||||
|
||||
;; Restore Comp5: its main comes back up to date
|
||||
(restore-comp-5)
|
||||
(validate #(t/is (= (fill-colors %) ["#FF0000" "#FF0000" "#FF0000" "#FF0000"]))))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user