🐛 Fix plugin parse-point returning plain map instead of Point record (#9129)

The plugin parser's parse-point returned a plain `{:x … :y …}` map,
but shape interaction schemas (for example schema:open-overlay-interaction)
require the attribute to be a `::gpt/point` record. `(instance? Point {:x 0 :y 0})`
is false, so validation silently rejected plugin `addInteraction` calls
that passed `manualPositionLocation`; only a console warning was produced.

Change parse-point to return a `gpt/point` record via `gpt/point`.
All three call sites (parser.cljs:open-overlay, plugins/page.cljs,
plugins/comments.cljs) continue to work because Point records support
the same `:x`/`:y` access plain maps do.

Add a unit test that covers nil input and verifies the returned value
satisfies `gpt/point?`.

Github #8409

Signed-off-by: FairyPigDev <luislee3108@gmail.com>
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
Co-authored-by: Andrey Antukh <niwi@niwi.nz>
This commit is contained in:
FairyPiggyDev 2026-04-24 03:12:13 -04:00 committed by GitHub
parent 841b2e156e
commit 361c1c574b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 2 deletions

View File

@ -78,6 +78,7 @@
- Fix copy to be more specific [Taiga #13990](https://tree.taiga.io/project/penpot/issue/13990)
- Allow deleting the profile avatar after uploading [Github #9067](https://github.com/penpot/penpot/issues/9067)
- Fix incorrect rendering when exporting text as SVG, PNG and JPG (by @edwin-rivera-dev) [Github #8516](https://github.com/penpot/penpot/issues/8516)
- Fix plugin `addInteraction` silently rejecting `open-overlay` actions with `manualPositionLocation` [Github #8409](https://github.com/penpot/penpot/issues/8409)
- Fix typography style creation with tokenized line-height (by @juan-flores077) [Github #8479](https://github.com/penpot/penpot/issues/8479)
## 2.16.0 (Unreleased)

View File

@ -7,6 +7,7 @@
(ns app.plugins.parser
(:require
[app.common.data :as d]
[app.common.geom.point :as gpt]
[app.common.json :as json]
[app.common.types.path :as path]
[app.common.uuid :as uuid]
@ -26,10 +27,16 @@
(if (string? color) (-> color str/lower) color))
(defn parse-point
"Parses a point-like JS object into a `gpt/point` record.
The schema for shape interactions (`schema:open-overlay-interaction`,
`::gpt/point`) requires a Point record — returning a plain map caused
plugin `addInteraction` calls with an `open-overlay` action and a
`manualPositionLocation` to be silently rejected. See issue #8409."
[^js point]
(when point
{:x (obj/get point "x")
:y (obj/get point "y")}))
(gpt/point (obj/get point "x")
(obj/get point "y"))))
(defn parse-shape-type
[type]

View File

@ -0,0 +1,33 @@
;; 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 frontend-tests.plugins.parser-test
(:require
[app.common.geom.point :as gpt]
[app.plugins.parser :as parser]
[cljs.test :as t :include-macros true]))
(t/deftest test-parse-point-returns-gpt-point-record
;; Regression test for issue #8409.
;;
;; The plugin parser used to return a plain map `{:x … :y …}`, but the
;; shape-interaction schema expects `::gpt/point` (a Point record).
;; Plugin `addInteraction` calls with an `open-overlay` action and
;; `manualPositionLocation` were silently rejected by validation.
(t/testing "parse-point returns nil for nil input"
(t/is (nil? (parser/parse-point nil))))
(t/testing "parse-point returns a gpt/point record for valid input"
(let [result (parser/parse-point #js {:x 10 :y 20})]
(t/is (gpt/point? result))
(t/is (= 10 (:x result)))
(t/is (= 20 (:y result)))))
(t/testing "parse-point passes gpt/point? for a zero point"
(let [result (parser/parse-point #js {:x 0 :y 0})]
(t/is (gpt/point? result))
(t/is (= 0 (:x result)))
(t/is (= 0 (:y result))))))

View File

@ -20,6 +20,7 @@
[frontend-tests.logic.pasting-in-containers-test]
[frontend-tests.main-errors-test]
[frontend-tests.plugins.context-shapes-test]
[frontend-tests.plugins.parser-test]
[frontend-tests.svg-fills-test]
[frontend-tests.tokens.import-export-test]
[frontend-tests.tokens.logic.token-actions-test]
@ -63,6 +64,7 @@
'frontend-tests.logic.groups-test
'frontend-tests.logic.pasting-in-containers-test
'frontend-tests.plugins.context-shapes-test
'frontend-tests.plugins.parser-test
'frontend-tests.svg-fills-test
'frontend-tests.tokens.import-export-test
'frontend-tests.tokens.logic.token-actions-test