Commit Graph

20612 Commits

Author SHA1 Message Date
Andrey Antukh
25df9f2f83 🐛 Fix DataCloneError in plugin postMessage communication
Fixes a crash where plugins sending messages via 'penpot.ui.sendMessage()'
could fail if their message payload contained non-serializable values like
functions or closures.

The fix adds validation using 'structuredClone()' to catch these messages
early with a helpful error message, and adds a defensive try/catch in the
modal's message handler as a safety net.

Fixes the error: 'Failed to execute postMessage on Window: ... could not
be cloned.'

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 15:26:00 +01:00
Alejandro Alonso
be9b1158ed Merge pull request #8588 from penpot/niwinz-staging-abort-signal-fix
🐛 Fix unhandled AbortError in HTTP fetch requests
2026-03-12 13:53:18 +01:00
Eva Marco
8f5c38d476 🐛 Fix scroll on colorpicker (#8595) 2026-03-12 13:36:38 +01:00
Andrey Antukh
80d165ed5b 🐛 Fix unhandled AbortError in HTTP fetch requests
Identify and silence "signal is aborted without reason" errors by:
- Providing an explicit reason to AbortController when subscriptions are disposed.
- Updating the global error handler to ignore AbortError exceptions.
- Ensuring unhandled rejections use the ignorable exception filter.

The root cause was RxJS disposal calling .abort() without a reason, combined
with the on-unhandled-rejection handler missing the ignorable error filter.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 13:31:58 +01:00
Alejandro Alonso
4b330e7b50 Merge pull request #8596 from penpot/niwinz-staging-fix-max-recursion
🐛 Fix RangeError (stack overflow) in find-component-main
2026-03-12 13:30:16 +01:00
Alejandro Alonso
f5cabac5f3 Merge pull request #8583 from penpot/niwinz-staging-ignore-extensions-exceptions
🐛 Ignore browser extension errors in unhandled exception handler
2026-03-12 13:20:11 +01:00
Alejandro Alonso
1487386fbb Merge pull request #8582 from penpot/niwinz-staging-bugfix-path-plain-content
🐛 Fix plain vector leaking into shape :content from shape-to-path
2026-03-12 13:15:14 +01:00
Andrey Antukh
b68e400cc1 🐛 Fix crash in select* when options vector is empty (#8578)
Guard get-option fallback with (when (seq options) ...) to avoid
"No item 0 in vector of length 0" when options is an empty vector.
Also guard the selected-option memo in select* to mirror the same
pattern already present in combobox*.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 13:06:25 +01:00
Alejandro Alonso
50c27aecc7 Merge pull request #8574 from penpot/niwinz-staging-unmount-fixes
🐛 Fix removeChild crash on portal-on-document* unmount
2026-03-12 13:06:00 +01:00
Alejandro Alonso
c254f88367 Merge pull request #8575 from penpot/niwinz-staging-fetch-exception
🐛 Wrap fetch TypeError into proper ex-info with :unable-to-fetch code
2026-03-12 12:48:48 +01:00
Alejandro Alonso
8f7b12dfd8 Merge pull request #8569 from penpot/niwinz-staging-bugfix-2-not-iseqable-exception
🐛 Fix 'not ISeqable' error when entering float values in layout/opacity inputs
2026-03-12 12:37:35 +01:00
Andrey Antukh
82e3a5fa53 🐛 Fix 'not ISeqable' error when entering float values in layout/opacity inputs
Replace int? with number? in on-change handlers for layout item margins,
min/max sizes, and layer opacity. Using int? caused float values like 8.5
to fall into the design token branch, calling (first 8.5) and crashing.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 12:37:22 +01:00
Alejandro Alonso
1680be33ef Merge pull request #8568 from penpot/niwinz-staging-bugfix-1-path-get-points
🐛 Fix TypeError when path content is nil in get-points calls
2026-03-12 12:31:58 +01:00
Andrey Antukh
6ee8184821 🐛 Fix error when creating guides without frame (#8598)
* 🐛 Fix error when creating guides without frame

The error 'Cannot read properties of undefined (reading
$cljs$core$IFn$_invoke$arity$0$)' occurred when creating a new
guide. It is probably a race condition because it is not reproducible
from the user point of view.

The cause is mainly because of use incorrect jsx handler :& where :>
should be used. This caused that some props pased with incorrect casing
and the relevant callback props received as nil on the component and
on the use-guide hook.

The fix is simple: use correct jsx handler

Signed-off-by: Andrey Antukh <niwi@niwi.nz>

* 💄 Add cosmetic changes to viewport guides components

---------

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-12 12:23:09 +01:00
Eva Marco
c00ef7c128 🐛 Fix unnexpected warning (#8603) 2026-03-12 12:01:28 +01:00
Xaviju
9b3207b06c 🐛 Fix wrong value on property copy on inspect styles (#8605) 2026-03-12 11:45:16 +01:00
Andrey Antukh
11a1ac2a09 🐛 Fix RangeError (stack overflow) in find-component-main
Refactor find-component-main to use an iterative loop/recur pattern instead of direct recursion and added cycle detection for malformed data structures.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-11 16:15:47 +01:00
Alonso Torres
31a4a7f21f 💄 Removed forgotten print (#8594) 2026-03-11 16:04:33 +01:00
Andrey Antukh
7ec9261475 Add improvements to AGENTS.md (#8586) 2026-03-11 15:24:40 +01:00
David Barragán Merino
e855907b05 🔧 Disable search indexing of plugin docs for non-production envs 2026-03-10 19:36:28 +01:00
Andrey Antukh
db9e9f4832 🐛 Ignore browser extension errors in unhandled exception handler
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 19:30:01 +01:00
Andrey Antukh
7939cb045b 🐛 Fix plain vector leaking into shape :content from shape-to-path conversions
group-to-path was storing a raw concatenated vector into :content after
flattening children's PathData instances via (map vec). bool-to-path
was storing the plain-vector result of bool/calculate-content directly.
Both now wrap through path.impl/path-data at the assignment site so the
:content invariant (always a PathData instance) is upheld.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 19:26:03 +01:00
Andrey Antukh
f566a2adfd 🐛 Fix ITransformable error when path content is a plain vector
Coerce content to PathData in transform-content before dispatching
the ITransformable protocol, so shapes carrying a plain vector in
their :content field (legacy data, bool shapes, SVG imports) no
longer crash with 'No protocol method ITransformable.-transform
defined for type object'.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 18:06:44 +00:00
Andrey Antukh
31d8b35a2c 📎 Revert small changes related to browser pool on exporter 2026-03-10 18:51:04 +01:00
Andrey Antukh
fed01fba73 🐛 Wrap fetch TypeError into proper ex-info with :unable-to-fetch code
Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 15:59:14 +01:00
Andrey Antukh
4f0bceddae 🐛 Fix stale deferred DOM ops in dashboard navigation
Two related issues that could cause crashes during fast navigation
in the dashboard:

1. grid.cljs: On drag-start, a temporary counter element is appended
   to the file card node for the drag ghost image, then scheduled for
   removal via requestAnimationFrame. If the user navigates away before
   the RAF fires, React unmounts the section and removes the card node
   from the DOM. When the RAF fires, item-el.removeChild(counter-el)
   throws because counter-el is no longer a child. Fixed by guarding
   the removal with dom/child?.

2. sidebar.cljs: Keyboard navigation handlers used ts/schedule-on-idle
   (requestIdleCallback with a 30s timeout) to focus the newly rendered
   section title after navigation. This left a very wide window for the
   callback to fire against a stale DOM after a subsequent navigation.
   Additionally, the idle callbacks were incorrectly passed as arguments
   to st/emit! (which ignores non-event values), making the scheduling
   an accidental side effect. Fixed by replacing all occurrences with
   ts/schedule (setTimeout 0), which is sufficient to defer past the
   current render cycle, and moving the calls outside st/emit!.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 14:22:45 +00:00
Andrey Antukh
80b64c440c 🐛 Fix removeChild crash on portal-on-document* unmount
The previous implementation passed document.body directly as the
React portal containerInfo. During unmount, React's commit phase
(commitUnmountFiberChildrenRecursively, case 4) sets the current
container to containerInfo and then calls container.removeChild()
for every DOM node inside the portal tree.

When two concurrent state updates are processed — e.g. navigating
away from a dashboard section while a file-menu portal is open —
React could attempt document.body.removeChild(node) twice for the
same node, the second time throwing:

  NotFoundError: Failed to execute 'removeChild' on 'Node':
  The node to be removed is not a child of this node.

The fix allocates a dedicated <div> container per portal instance
via mf/use-memo. The container is appended to body on mount and
removed in the effect cleanup. React then owns an exclusive
containerInfo and its unmount path never races with another
portal or the modal container (which also targets document.body).

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 14:22:34 +00:00
Andrey Antukh
98c1503bca Backport serveral plugin types documentation 2026-03-10 15:05:08 +01:00
Andrey Antukh
9f66220caa 🐛 Fix flex layout container horizontalSizing/verticalSizing via plugin API (#8555)
Setting horizontalSizing/verticalSizing on a FlexLayoutProxy was
dispatching update-layout-child instead of update-layout, so the
frame's auto-sizing (hug content) was never triggered even though
the getter read back the value correctly.

Also restricts accepted values to #{:fix :auto} (matching shape.cljs)
since frames cannot use :fill, and fixes a copy-paste error that
reported :horizontalPadding instead of :horizontalSizing in error messages.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2.14.0-RC3
2026-03-10 15:01:23 +01:00
Aitor Moreno
3112b0d8cf 🐛 Fix grow options not verifying text-editor/v2 (#8571) 2026-03-10 15:01:23 +01:00
Andrey Antukh
ab90500ec8 🐛 Fix download-image to properly handle network errors and non-2xx responses (#8554)
The download-image function in app.media silently succeeded when the
remote image URL was unreachable or returned an error status code,
causing create-file-media-object-from-url to report success with no
actual image stored.

Add exception handling for connection refused, timeouts, and I/O errors
around the HTTP request, and validate the HTTP status code in
parse-and-validate before processing the response body.

Fixes #8499

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 15:01:23 +01:00
Andrey Antukh
0f47c30349 Merge branch 'main' into staging 2026-03-10 14:39:16 +01:00
Andrey Antukh
68fbacf8b3 Merge tag '2.14.0-RC2' 2026-03-10 14:38:58 +01:00
Andrey Antukh
7ab5f241da 🐛 Fix TypeError when path content is nil in get-points calls
Use nil-safe path/get-points wrapper (some-> based) instead of
direct path.segment/get-points calls in edition.cljs to prevent
'Cannot read properties of undefined (reading get)' crash.

Add nil-safety test to verify path/get-points returns nil without
throwing when content is nil.

Signed-off-by: Andrey Antukh <niwi@niwi.nz>
2026-03-10 12:21:13 +00:00
Andrey Antukh
32cf95265a 📚 Add GitHub Copilot instructions (#8548) 2026-03-10 13:12:15 +01:00
Pablo Alba
34d29328e6 🐛 Fix bad size on switching a layout with fixed sizing (#8504) 2.14.0-RC2 2026-03-09 12:12:03 +01:00
Eva Marco
c59cc4dff4 🐛 Fix tooltip position on absolute positioned elements (#8509)
* 🐛 Fix tooltip position on absolute positioned elements

* 🐛 Fix tests
2026-03-09 12:11:39 +01:00
Andrey Antukh
0ceadada35 🐛 Fix invalid data on layout flex dir shape property 2026-03-09 10:09:07 +01:00
Andrey Antukh
77955d7f91 Add several redundant checks for library-id on file rpc methods 2026-03-09 10:01:29 +01:00
Andrey Antukh
151238e518 💄 Add cosmetic change to link-file-to-library rpc method impl 2026-03-09 10:01:29 +01:00
Andrey Antukh
591d63e470 Add better error report on wrong input on logging helpers 2026-03-09 10:01:09 +01:00
andrés gonzález
5a6be141fd 📚 Add info about using math in tokens (#8510) 2026-03-04 14:59:04 +01:00
Eva Marco
cc3033735b 🐛 Fix showing warning when no shape is selected (#8515) 2026-03-04 10:58:36 +01:00
Xaviju
e1d556f4aa 🐛 Sort tokens by name (#8488) 2026-03-04 10:33:29 +01:00
Andrey Antukh
c3f5117757 🐛 Fix unhandled exception on using decimals on stroke row (#8405) 2026-03-04 09:47:14 +01:00
Andrey Antukh
86e851f408 🐛 Fix incorrect version visibility on workspace (#8463)
* 🐛 Add missing order by clause to snapshot query

This fixes the incorrect snapshot visibility when file
has a lot of versions.

*  Reduce allocation on milestone-group* component

* 🐛 Fix milestone group timestamp formatting

* 📎 Update changelog

* 🐛 Fix scroll on history panel

---------

Co-authored-by: Eva Marco <evamarcod@gmail.com>
2026-03-04 09:27:51 +01:00
Andrey Antukh
a4351d133b Add minor improvements to error reporting (#8402) 2026-03-04 09:12:19 +01:00
Andrey Antukh
b704a7da0e 🐛 Fix inconsistency between plugins api doc and impl for shadows (#8454)
Related to offset-x and offset-y attributes.
2026-03-04 09:09:27 +01:00
Andrey Antukh
478f631df5 🐛 Don't throw exception when picker is closed and image is still uploading (#8453)
*  Add notification tag to media uploading

This avoid hidding error messages once the upload
is finished.

* 🐛 Don't throw exception when picker is closed and image is still uploading
2026-03-04 09:07:15 +01:00
Andrey Antukh
57b9efbcd7 🐛 Fix redo operation on commenting on workspace (#8455) 2026-03-03 09:50:23 +01:00