mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
The with-cache macro in impl.cljc assumed the target was always a PathData instance (which has a cache field). When content was a plain vector, (.-cache content) returned undefined in JS, causing: TypeError: Cannot read properties of undefined (reading 'get') Fix: - path/get-points (app.common.types.path) is now the canonical safe entry point: converts non-PathData content via impl/path-data and handles nil safely before delegating to segment/get-points - segment/get-points remains a low-level function that expects a PathData instance (no defensive logic at that level) - streams.cljs: replace direct call to path.segm/get-points with path/get-points so the safe conversion path is always used - with-cache macro: guards against nil/undefined cache, falling back to direct evaluation for non-PathData targets Signed-off-by: Andrey Antukh <niwi@niwi.nz>
92 lines
3.0 KiB
Clojure
92 lines
3.0 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS INC
|
|
|
|
(ns app.main.data.workspace.path.changes
|
|
(:require
|
|
[app.common.data.macros :as dm]
|
|
[app.common.files.changes-builder :as pcb]
|
|
[app.common.types.path :as path]
|
|
[app.main.data.changes :as dch]
|
|
[app.main.data.helpers :as dsh]
|
|
[app.main.data.workspace.path.state :as st]
|
|
[beicon.v2.core :as rx]
|
|
[potok.v2.core :as ptk]))
|
|
|
|
(defn generate-path-changes
|
|
"Generates changes to update the new content of the shape"
|
|
[it objects page-id shape old-content new-content]
|
|
|
|
(assert (path/content? old-content))
|
|
(assert (path/content? new-content))
|
|
|
|
(let [shape-id (:id shape)
|
|
|
|
;; We set the old values so the update-shapes works
|
|
objects
|
|
(update objects shape-id
|
|
(fn [shape]
|
|
(-> shape
|
|
(assoc :content old-content)
|
|
(path/update-geometry))))
|
|
|
|
changes
|
|
(-> (pcb/empty-changes it page-id)
|
|
(pcb/with-objects objects))
|
|
|
|
new-content
|
|
(path/content new-content)]
|
|
|
|
(cond
|
|
;; https://tree.taiga.io/project/penpot/issue/2366
|
|
(nil? shape-id)
|
|
changes
|
|
|
|
(empty? new-content)
|
|
(-> changes
|
|
(pcb/remove-objects [shape-id])
|
|
(pcb/resize-parents [shape-id]))
|
|
|
|
:else
|
|
(-> changes
|
|
(pcb/update-shapes [shape-id]
|
|
(fn [shape]
|
|
(-> shape
|
|
(assoc :content new-content)
|
|
(path/update-geometry))))
|
|
(pcb/resize-parents [shape-id])))))
|
|
|
|
(defn save-path-content
|
|
([]
|
|
(save-path-content {}))
|
|
([{:keys [preserve-move-to] :or {preserve-move-to false}}]
|
|
(ptk/reify ::save-path-content
|
|
ptk/UpdateEvent
|
|
(update [_ state]
|
|
(let [content (st/get-path state :content)
|
|
content (if (and (not preserve-move-to)
|
|
(= (-> content last :command) :move-to))
|
|
(path/content (take (dec (count content)) content))
|
|
content)]
|
|
(st/set-content state content)))
|
|
|
|
ptk/WatchEvent
|
|
(watch [it state _]
|
|
(let [page-id (:current-page-id state)
|
|
local (get state :workspace-local)
|
|
id (get local :edition)
|
|
objects (dsh/lookup-page-objects state page-id)]
|
|
|
|
;; NOTE: we proceed only if the shape is present on the
|
|
;; objects, if shape is a ephimeral drawing shape, we should
|
|
;; do nothing
|
|
(when-let [shape (get objects id)]
|
|
(when-let [old-content (dm/get-in local [:edit-path id :old-content])]
|
|
(let [new-content (get shape :content)
|
|
changes (generate-path-changes it objects page-id shape old-content new-content)]
|
|
(rx/of (dch/commit-changes changes))))))))))
|
|
|
|
|