mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 14:00:37 +00:00
🐛 Walk a ref chain to its target and across containers
get-ref-chain-until-target-ref, which the keep-touched variant switch and the paste of a nested copy use to collect the touched groups along a copy's ref chain, had two faults: - it compared each shape with the target's id, so it never stopped at the target and merged the touched groups of the whole chain (F62): a copy pasted out of its main could take overrides its new near main does not have; - it looked each next link up in the container it started in, so a chain whose next main lives on another page, or in a library, stopped after one link and missed the groups beyond it (F31). It now compares ids and takes each link's own container. The golden master and the composable cases are unchanged: none of them reaches a chain past its target or across containers with an override. file-test checks both: the chain stops at a target in its middle, and it follows a copy on one page through mains on another. Benchmark (lower quantile, ms; baseline / now / ratio): deepest-edit-through-three-levels 35.2 / 16.0 / 0.45 edit-through-a-chain-of-dependents 68.9 / 33.7 / 0.49 library-update-into-copies 83.1 / 38.6 / 0.46 main-edit-among-many-shapes 4.8 / 2.2 / 0.46 main-edit-into-10-copies 1.8 / 0.7 / 0.42 main-edit-into-100-copies 15.4 / 7.1 / 0.46 main-edit-into-1000-copies 153.1 / 77.2 / 0.50 variant-switch-into-copies 32.1 / 17.1 / 0.53 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
a5ad3caffe
commit
3db2871469
@ -1230,14 +1230,17 @@
|
||||
|
||||
;; Ref Chains
|
||||
(defn get-ref-chain-until-target-ref
|
||||
"Returns a vector with the shape ref chain until target-ref, including itself"
|
||||
"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."
|
||||
[container libraries shape target-ref]
|
||||
(loop [chain [shape]
|
||||
current shape]
|
||||
(if (= current 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)]
|
||||
(recur (conj chain ref) ref)
|
||||
(recur (conj chain ref) ref (:container (meta ref)))
|
||||
chain))))
|
||||
|
||||
(defn get-touched-from-ref-chain-until-target-ref
|
||||
|
||||
@ -320,11 +320,20 @@
|
||||
copy-c1 (ths/get-shape-by-id file (first (:shapes (ths/get-shape-by-id file copy-c2))))
|
||||
chain (ctf/get-ref-chain-until-target-ref (thf/current-page file) {(:id file) file}
|
||||
copy-c1 (thi/id :nested-subhead2))]
|
||||
;; the stop compares each shape with the target's id, so it never holds
|
||||
(tm/known-failure "F62"
|
||||
[(:id copy-c1) (thi/id :nested-subhead2)]
|
||||
[(:id copy-c1) (thi/id :nested-subhead2) (thi/id :nested-head1) (thi/id :main1)]
|
||||
(mapv :id chain))))
|
||||
(t/is (= [(:id copy-c1) (thi/id :nested-subhead2)] (mapv :id chain)))))
|
||||
|
||||
(t/deftest ref-chain-follows-mains-on-other-pages
|
||||
;; the mains are on the first page, the copy on the second
|
||||
(let [file (-> (thf/sample-file :file :page-label :page1)
|
||||
(tho/add-nested-component :c1 :main1 :main1-child :c2 :main2 :nested-head)
|
||||
(thf/add-sample-page :page2)
|
||||
(thc/instantiate-component :c2 :copy2))
|
||||
copy-head (ths/get-shape-by-id file (first (:shapes (ths/get-shape file :copy2))))
|
||||
copy-child (ths/get-shape-by-id file (first (:shapes copy-head)))
|
||||
near-child (first (:shapes (ths/get-shape file :nested-head :page-label :page1)))
|
||||
chain (ctf/get-ref-chain-until-target-ref (thf/current-page file) {(:id file) file}
|
||||
copy-child nil)]
|
||||
(t/is (= [(:id copy-child) near-child (thi/id :main1-child)] (mapv :id chain)))))
|
||||
|
||||
(t/deftest near-match-with-context
|
||||
(let [file (-> (thf/sample-file :file)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user