mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Stop inherited content overrides at swapped references
Walk content refs through intermediate swapped heads when collecting inherited touched groups. Following the replaced position instead crosses into another component and gives copies phantom geometry overrides (F165). Position advancement keeps its separate position-ref walk. A portable three-level regression fails both chain and touched assertions before the fix. Swap-group, file and variant suites pass 124 tests and 588 assertions; the shrunk library seed-712 program passes as well. Common lint and format pass. Benchmark lower-quantile ratios against Phase 1e: main 10/100/1000 copies 0.48/0.55/0.57, three levels 0.48, chain 0.47, library 0.49, many shapes 0.46, variant switch 0.57. No regression flags. AI-assisted-by: GPT-6
This commit is contained in:
parent
a37fac788c
commit
357e8a7ff7
@ -66,3 +66,9 @@ Moving/dropping a shape into a variant container through the move-to-frame path
|
||||
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).
|
||||
|
||||
Content ref chains (get-ref-chain-until-target-ref, including touched walks)
|
||||
take find-content-ref-shape at every link. A swapped intermediate head
|
||||
follows its own main; collecting its replaced position's content overrides
|
||||
creates phantom groups in copies of that swap (F165). Position advancement
|
||||
still uses advance-shape-ref and find-ref-shape.
|
||||
|
||||
@ -1257,16 +1257,16 @@
|
||||
|
||||
;; Ref Chains
|
||||
(defn get-ref-chain-until-target-ref
|
||||
"The shape `shape` of `container` and its ref chain (each shape's near
|
||||
main, found in the container of the one before), up to the shape whose id
|
||||
is `target-ref`, included, or to the end of the chain."
|
||||
"The shape `shape` of `container` and its content ref chain, up to the
|
||||
shape whose id is `target-ref`, included, or to the end of the chain.
|
||||
A swapped head follows its own component, not the replaced position."
|
||||
[container libraries shape target-ref]
|
||||
(loop [chain [shape]
|
||||
current shape
|
||||
container container]
|
||||
(if (= (:id current) target-ref)
|
||||
chain
|
||||
(if-let [ref (find-ref-shape nil container libraries current :with-context? true)]
|
||||
(if-let [ref (find-content-ref-shape nil container libraries current :with-context? true)]
|
||||
(recur (conj chain ref) ref (:container (meta ref)))
|
||||
chain))))
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
[app.common.test-helpers.variants :as thv]
|
||||
[app.common.types.component :as ctk]
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.common.types.modifiers :as ctm]
|
||||
[clojure.test :as t]))
|
||||
|
||||
@ -877,3 +878,24 @@
|
||||
swapped (-> initial (r/step (n/swap-shape :card-star :heart)) r/settle)
|
||||
undone (r/step swapped (n/undo))]
|
||||
(t/is (= (thn/normalize-file file) (thn/normalize-file (tm/file undone))))))
|
||||
|
||||
(t/deftest inherited-content-overrides-stop-at-a-swapped-reference
|
||||
(let [file (-> (thf/sample-file :file)
|
||||
(tho/add-two-levels-nested-component-with-copy
|
||||
:c1 :main1 :main1-child :c2 :main2 :nested-head1
|
||||
:c3 :main3 :nested-head2 :nested-subhead2 :copy3)
|
||||
(tho/add-simple-component :other :other-main :other-child))
|
||||
file (-> (tm/make-situation file)
|
||||
(r/step (n/change-property :nested-head1 :opacity 0.4))
|
||||
tm/file
|
||||
(tho/swap-component-in-shape :nested-subhead2 :other
|
||||
:propagate-fn #(propagate % :c3)))
|
||||
page (thf/current-page file)
|
||||
middle (ths/get-shape-by-id file (first (:shapes (ths/get-shape file :copy3))))
|
||||
child (ths/get-shape-by-id file (first (:shapes middle)))
|
||||
libraries {(:id file) file}
|
||||
chain (ctf/get-ref-chain-until-target-ref page libraries child nil)]
|
||||
(t/is (= [(:id child) (thi/id :nested-subhead2) (thi/id :other-main)]
|
||||
(mapv :id chain)))
|
||||
(t/is (= #{:swap-group}
|
||||
(ctf/get-touched-from-ref-chain-until-target-ref page libraries child nil)))))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user