mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Fix TypeError in get-points when content is not PathData (#8634)
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>
This commit is contained in:
parent
efd6d19a12
commit
0779c9ca61
@ -190,10 +190,14 @@
|
|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defn get-points
|
(defn get-points
|
||||||
"Returns points for the given segment, faster version of
|
"Returns points for the given content. Accepts PathData instances or
|
||||||
the `content->points`."
|
plain segment vectors. Returns nil for nil content."
|
||||||
[content]
|
[content]
|
||||||
(some-> content segment/get-points))
|
(when (some? content)
|
||||||
|
(let [content (if (impl/path-data? content)
|
||||||
|
content
|
||||||
|
(impl/path-data content))]
|
||||||
|
(segment/get-points content))))
|
||||||
|
|
||||||
(defn calc-selrect
|
(defn calc-selrect
|
||||||
"Calculate selrect from a content. The content can be in a PathData
|
"Calculate selrect from a content. The content can be in a PathData
|
||||||
|
|||||||
@ -52,14 +52,15 @@
|
|||||||
[target key & expr]
|
[target key & expr]
|
||||||
(if (:ns &env)
|
(if (:ns &env)
|
||||||
(let [target (with-meta target {:tag 'js})]
|
(let [target (with-meta target {:tag 'js})]
|
||||||
`(let [~'cache (.-cache ~target)
|
`(let [~'cache (.-cache ~target)]
|
||||||
~'result (.get ~'cache ~key)]
|
(if (some? ~'cache)
|
||||||
(if ~'result
|
(let [~'result (.get ~'cache ~key)]
|
||||||
(do
|
(if ~'result
|
||||||
~'result)
|
~'result
|
||||||
(let [~'result (do ~@expr)]
|
(let [~'result (do ~@expr)]
|
||||||
(.set ~'cache ~key ~'result)
|
(.set ~'cache ~key ~'result)
|
||||||
~'result))))
|
~'result)))
|
||||||
|
(do ~@expr))))
|
||||||
`(do ~@expr)))
|
`(do ~@expr)))
|
||||||
|
|
||||||
(defn- impl-transform-segment
|
(defn- impl-transform-segment
|
||||||
|
|||||||
@ -279,6 +279,12 @@
|
|||||||
(t/is (some? points))
|
(t/is (some? points))
|
||||||
(t/is (= 3 (count points))))))
|
(t/is (= 3 (count points))))))
|
||||||
|
|
||||||
|
(t/deftest path-get-points-plain-vector-safe
|
||||||
|
(t/testing "path/get-points does not throw for plain vector content"
|
||||||
|
(let [points (path/get-points sample-content)]
|
||||||
|
(t/is (some? points))
|
||||||
|
(t/is (= 3 (count points))))))
|
||||||
|
|
||||||
(defn calculate-extremities
|
(defn calculate-extremities
|
||||||
"Calculate extremities for the provided content.
|
"Calculate extremities for the provided content.
|
||||||
A legacy implementation used mainly as reference for testing"
|
A legacy implementation used mainly as reference for testing"
|
||||||
|
|||||||
@ -68,7 +68,7 @@
|
|||||||
(let [content (st/get-path state :content)
|
(let [content (st/get-path state :content)
|
||||||
content (if (and (not preserve-move-to)
|
content (if (and (not preserve-move-to)
|
||||||
(= (-> content last :command) :move-to))
|
(= (-> content last :command) :move-to))
|
||||||
(into [] (take (dec (count content)) content))
|
(path/content (take (dec (count content)) content))
|
||||||
content)]
|
content)]
|
||||||
(st/set-content state content)))
|
(st/set-content state content)))
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
(:require
|
(:require
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[app.common.geom.point :as gpt]
|
[app.common.geom.point :as gpt]
|
||||||
[app.common.types.path.segment :as path.segm]
|
[app.common.types.path :as path]
|
||||||
[app.main.data.workspace.path.state :as pst]
|
[app.main.data.workspace.path.state :as pst]
|
||||||
[app.main.snap :as snap]
|
[app.main.snap :as snap]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
@ -167,7 +167,7 @@
|
|||||||
ranges-stream
|
ranges-stream
|
||||||
(->> content-stream
|
(->> content-stream
|
||||||
(rx/filter some?)
|
(rx/filter some?)
|
||||||
(rx/map path.segm/get-points)
|
(rx/map path/get-points)
|
||||||
(rx/map snap/create-ranges))]
|
(rx/map snap/create-ranges))]
|
||||||
|
|
||||||
(->> ms/mouse-position
|
(->> ms/mouse-position
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user