mirror of
https://github.com/penpot/penpot.git
synced 2025-06-01 04:41:40 +02:00
♻️ Refactor update attrs
* Extract token update from update-attrs * Split update-attrs in smaller functions for legibility and reusability
This commit is contained in:
parent
86a498fc29
commit
ee0ba15f9e
1 changed files with 83 additions and 80 deletions
|
@ -1605,6 +1605,75 @@
|
||||||
:val dest-tokens
|
:val dest-tokens
|
||||||
:ignore-touched true}]}))))))
|
:ignore-touched true}]}))))))
|
||||||
|
|
||||||
|
(defn- generate-update-tokens
|
||||||
|
[changes container dest-shape origin-shape touched omit-touched?]
|
||||||
|
(let [attrs (->> (seq (keys ctk/sync-attrs))
|
||||||
|
;; We don't update the flex-child attrs
|
||||||
|
(remove #(= :layout-grid-cells %)))
|
||||||
|
|
||||||
|
applied-tokens (reduce (fn [applied-tokens attr]
|
||||||
|
(let [attr-group (get ctk/sync-attrs attr)
|
||||||
|
token-attrs (cto/shape-attr->token-attrs attr)]
|
||||||
|
(if (not (and (touched attr-group)
|
||||||
|
omit-touched?))
|
||||||
|
(into applied-tokens token-attrs)
|
||||||
|
applied-tokens)))
|
||||||
|
#{}
|
||||||
|
attrs)]
|
||||||
|
(cond-> changes
|
||||||
|
(seq applied-tokens)
|
||||||
|
(update-tokens container dest-shape origin-shape applied-tokens))))
|
||||||
|
|
||||||
|
(defn- add-update-attr-changes
|
||||||
|
[changes dest-shape container roperations uoperations]
|
||||||
|
(let [all-parents (cfh/get-parent-ids (:objects container)
|
||||||
|
(:id dest-shape))]
|
||||||
|
(-> changes
|
||||||
|
(update :redo-changes conj (make-change
|
||||||
|
container
|
||||||
|
{:type :mod-obj
|
||||||
|
:id (:id dest-shape)
|
||||||
|
:operations roperations}))
|
||||||
|
(update :redo-changes conj (make-change
|
||||||
|
container
|
||||||
|
{:type :reg-objects
|
||||||
|
:shapes all-parents}))
|
||||||
|
(update :undo-changes conj (make-change
|
||||||
|
container
|
||||||
|
{:type :mod-obj
|
||||||
|
:id (:id dest-shape)
|
||||||
|
:operations (vec uoperations)}))
|
||||||
|
(update :undo-changes concat [(make-change
|
||||||
|
container
|
||||||
|
{:type :reg-objects
|
||||||
|
:shapes all-parents})]))))
|
||||||
|
|
||||||
|
(defn- add-update-attr-operations
|
||||||
|
[attr dest-shape origin-shape roperations uoperations touched]
|
||||||
|
(let [;; position-data is a special case because can be affected by :geometry-group and :content-group
|
||||||
|
;; so, if the position-data changes but the geometry is touched we need to reset the position-data
|
||||||
|
;; so it's calculated again
|
||||||
|
reset-pos-data?
|
||||||
|
(and (cfh/text-shape? origin-shape)
|
||||||
|
(= attr :position-data)
|
||||||
|
(not= (get origin-shape attr) (get dest-shape attr))
|
||||||
|
(touched :geometry-group))
|
||||||
|
|
||||||
|
roperation {:type :set
|
||||||
|
:attr attr
|
||||||
|
:val (cond
|
||||||
|
;; If position data changes and the geometry group is touched
|
||||||
|
;; we need to put to nil so we can regenerate it
|
||||||
|
reset-pos-data? nil
|
||||||
|
:else (get origin-shape attr))
|
||||||
|
:ignore-touched true}
|
||||||
|
uoperation {:type :set
|
||||||
|
:attr attr
|
||||||
|
:val (get dest-shape attr)
|
||||||
|
:ignore-touched true}]
|
||||||
|
[(conj roperations roperation)
|
||||||
|
(conj uoperations uoperation)]))
|
||||||
|
|
||||||
(defn- update-attrs
|
(defn- update-attrs
|
||||||
"The main function that implements the attribute sync algorithm. Copy
|
"The main function that implements the attribute sync algorithm. Copy
|
||||||
attributes that have changed in the origin shape to the dest shape.
|
attributes that have changed in the origin shape to the dest shape.
|
||||||
|
@ -1640,92 +1709,26 @@
|
||||||
(remove ctk/swap-keep-attrs)
|
(remove ctk/swap-keep-attrs)
|
||||||
;; We don't do automatic update of the `layout-grid-cells` property.
|
;; We don't do automatic update of the `layout-grid-cells` property.
|
||||||
(remove #(= :layout-grid-cells %)))
|
(remove #(= :layout-grid-cells %)))
|
||||||
applied-tokens #{}
|
|
||||||
roperations []
|
roperations []
|
||||||
uoperations '()]
|
uoperations '()]
|
||||||
|
|
||||||
(let [attr (first attrs)]
|
(let [attr (first attrs)]
|
||||||
(if (nil? attr)
|
(if (nil? attr)
|
||||||
(if (and (empty? roperations) (empty? applied-tokens))
|
(cond-> changes
|
||||||
changes
|
(seq roperations)
|
||||||
(let [all-parents (cfh/get-parent-ids (:objects container)
|
(add-update-attr-changes dest-shape container roperations uoperations)
|
||||||
(:id dest-shape))
|
:always
|
||||||
|
(generate-update-tokens container dest-shape origin-shape touched omit-touched?))
|
||||||
|
|
||||||
;; Sync tokens of attributes ignored above.
|
(let [attr-group (get ctk/sync-attrs attr)
|
||||||
;; FIXME: this probably may be merged with the other calculation
|
[roperations' uoperations']
|
||||||
;; of applied tokens, below, and to the calculation only once
|
(if (or (= (get origin-shape attr) (get dest-shape attr))
|
||||||
;; for all sync-attrs.
|
(and (touched attr-group) omit-touched?))
|
||||||
applied-tokens (reduce (fn [applied-tokens attr]
|
[roperations uoperations]
|
||||||
(let [attr-group (get ctk/sync-attrs attr)
|
(add-update-attr-operations attr dest-shape origin-shape roperations uoperations touched))]
|
||||||
token-attrs (cto/shape-attr->token-attrs attr)]
|
(recur (next attrs)
|
||||||
(if (not (and (touched attr-group)
|
roperations'
|
||||||
omit-touched?))
|
uoperations')))))))
|
||||||
(into applied-tokens token-attrs)
|
|
||||||
applied-tokens)))
|
|
||||||
applied-tokens
|
|
||||||
ctk/swap-keep-attrs)]
|
|
||||||
(cond-> changes
|
|
||||||
(seq roperations)
|
|
||||||
(-> (update :redo-changes conj (make-change
|
|
||||||
container
|
|
||||||
{:type :mod-obj
|
|
||||||
:id (:id dest-shape)
|
|
||||||
:operations roperations}))
|
|
||||||
(update :redo-changes conj (make-change
|
|
||||||
container
|
|
||||||
{:type :reg-objects
|
|
||||||
:shapes all-parents}))
|
|
||||||
(update :undo-changes conj (make-change
|
|
||||||
container
|
|
||||||
{:type :mod-obj
|
|
||||||
:id (:id dest-shape)
|
|
||||||
:operations (vec uoperations)}))
|
|
||||||
(update :undo-changes concat [(make-change
|
|
||||||
container
|
|
||||||
{:type :reg-objects
|
|
||||||
:shapes all-parents})]))
|
|
||||||
(seq applied-tokens)
|
|
||||||
(update-tokens container dest-shape origin-shape applied-tokens))))
|
|
||||||
|
|
||||||
(let [;; position-data is a special case because can be affected by :geometry-group and :content-group
|
|
||||||
;; so, if the position-data changes but the geometry is touched we need to reset the position-data
|
|
||||||
;; so it's calculated again
|
|
||||||
reset-pos-data?
|
|
||||||
(and (cfh/text-shape? origin-shape)
|
|
||||||
(= attr :position-data)
|
|
||||||
(not= (get origin-shape attr) (get dest-shape attr))
|
|
||||||
(touched :geometry-group))
|
|
||||||
|
|
||||||
roperation {:type :set
|
|
||||||
:attr attr
|
|
||||||
:val (cond
|
|
||||||
;; If position data changes and the geometry group is touched
|
|
||||||
;; we need to put to nil so we can regenerate it
|
|
||||||
reset-pos-data? nil
|
|
||||||
:else (get origin-shape attr))
|
|
||||||
:ignore-touched true}
|
|
||||||
uoperation {:type :set
|
|
||||||
:attr attr
|
|
||||||
:val (get dest-shape attr)
|
|
||||||
:ignore-touched true}
|
|
||||||
|
|
||||||
attr-group (get ctk/sync-attrs attr)
|
|
||||||
|
|
||||||
token-attrs (cto/shape-attr->token-attrs attr)
|
|
||||||
applied-tokens' (cond-> applied-tokens
|
|
||||||
(not (and (touched attr-group)
|
|
||||||
omit-touched?))
|
|
||||||
(into token-attrs))]
|
|
||||||
(if (or (= (get origin-shape attr) (get dest-shape attr))
|
|
||||||
(and (touched attr-group) omit-touched?))
|
|
||||||
(recur (next attrs)
|
|
||||||
applied-tokens'
|
|
||||||
roperations
|
|
||||||
uoperations)
|
|
||||||
(recur (next attrs)
|
|
||||||
applied-tokens'
|
|
||||||
(conj roperations roperation)
|
|
||||||
(conj uoperations uoperation)))))))))
|
|
||||||
|
|
||||||
(defn- propagate-attrs
|
(defn- propagate-attrs
|
||||||
"Helper that puts the origin attributes (attrs) into dest but only if
|
"Helper that puts the origin attributes (attrs) into dest but only if
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue