diff --git a/.serena/memories/common/component-data-model.md b/.serena/memories/common/component-data-model.md index 2734207f9e..b8baf24fbd 100644 --- a/.serena/memories/common/component-data-model.md +++ b/.serena/memories/common/component-data-model.md @@ -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. diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index bea1989384..bdab828fba 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -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)))) diff --git a/common/test/common_tests/logic/swap_group_test.cljc b/common/test/common_tests/logic/swap_group_test.cljc index e7bc4676ec..45cc06ed89 100644 --- a/common/test/common_tests/logic/swap_group_test.cljc +++ b/common/test/common_tests/logic/swap_group_test.cljc @@ -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)))))