🐛 Add validation for current page on plugins API (#10271)

This commit is contained in:
Alonso Torres 2026-06-18 11:04:35 +02:00 committed by GitHub
parent 18c8769f05
commit a7e57c78cf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 1023 additions and 236 deletions

View File

@ -317,6 +317,9 @@
(or (not (array? shapes)) (not (every? shape/shape-proxy? shapes)))
(u/not-valid plugin-id :group-shapes shapes)
(some #(not (u/page-active? (obj/get % "$page"))) shapes)
(u/not-valid plugin-id :group "Cannot modify a page that is not currently active")
:else
(let [file-id (:current-file-id @st/state)
page-id (:current-page-id @st/state)
@ -335,6 +338,10 @@
(and (some? rest) (not (every? shape/shape-proxy? rest)))
(u/not-valid plugin-id :ungroup rest)
(or (not (u/page-active? (obj/get group "$page")))
(some #(not (u/page-active? (obj/get % "$page"))) rest))
(u/not-valid plugin-id :ungroup "Cannot modify a page that is not currently active")
:else
(let [shapes (concat [group] rest)
ids (into #{} (map #(obj/get % "$id")) shapes)]
@ -444,6 +451,9 @@
(or (not (array? shapes)) (empty? shapes) (not (every? shape/shape-proxy? shapes)))
(u/not-valid plugin-id :createBoolean-shapes shapes)
(some #(not (u/page-active? (obj/get % "$page"))) shapes)
(u/not-valid plugin-id :createBoolean "Cannot modify a page that is not currently active")
:else
(let [ids (into #{} (map #(obj/get % "$id")) shapes)
shape-id (uuid/next)]

View File

@ -136,6 +136,9 @@
(not (r/check-permission plugin-id "comment:write"))
(u/not-valid plugin-id :position "Plugin doesn't have 'comment:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :position "Cannot modify a page that is not currently active")
:else
(do (st/emit! (dwc/update-comment-thread-position @data* [(:x position) (:y position)]))
(swap! data* assoc :position (gpt/point position))))))}

View File

@ -44,6 +44,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :dir "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :dir "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-flex-dir value})))))}
@ -60,6 +63,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :wrap "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :wrap "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-wrap-type value})))))}
@ -76,6 +82,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignItems "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignItems "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
@ -92,6 +101,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignContent "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignContent "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
@ -108,6 +120,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :justifyItems "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :justifyItems "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
@ -124,6 +139,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :justifyContent "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :justifyContent "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
@ -139,6 +157,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rowGap "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rowGap "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}}))))}
@ -154,6 +175,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :columnGap "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :columnGap "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}}))))}
@ -169,6 +193,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}}))))}
@ -184,6 +211,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}}))))}
@ -199,6 +229,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :topPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :topPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}}))))}
@ -214,6 +247,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rightPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rightPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}}))))}
@ -229,6 +265,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :bottomPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :bottomPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}}))))}
@ -244,6 +283,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :leftPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :leftPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}}))))}
@ -257,6 +299,10 @@
(not (shape-proxy? child))
(u/not-valid plugin-id :appendChild child)
(or (not (u/page-active? page-id))
(not (u/page-active? (obj/get child "$page"))))
(u/not-valid plugin-id :appendChild "Cannot modify a page that is not currently active")
:else
(let [child-id (obj/get child "$id")
shape (u/locate-shape file-id page-id id)
@ -284,6 +330,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalSizing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalSizing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-item-h-sizing value})))))}
@ -300,6 +349,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalSizing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalSizing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-item-v-sizing value})))))}))
@ -326,6 +378,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :absolute "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :absolute "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-item-absolute value}))))}
@ -335,12 +390,15 @@
:set
(fn [_ value]
(cond
(sm/valid-safe-int? value)
(not (sm/valid-safe-int? value))
(u/not-valid plugin-id :zIndex value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :zIndex "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :zIndex "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-z-index value}))))}
@ -357,6 +415,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-h-sizing value})))))}
@ -373,6 +434,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalSizing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalSizing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-v-sizing value})))))}
@ -389,6 +453,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignSelf "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignSelf "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-align-self value})))))}
@ -404,6 +471,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value :m3 value}}))))}
@ -419,6 +489,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value :m4 value}}))))}
@ -434,6 +507,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :topMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :topMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m1 value}}))))}
@ -449,6 +525,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rightMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rightMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m2 value}}))))}
@ -464,6 +543,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :bottomMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :bottomMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m3 value}}))))}
@ -479,6 +561,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :leftMargin "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :leftMargin "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-margin {:m4 value}}))))}
@ -494,6 +579,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :maxWidth "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :maxWidth "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-w value}))))}
@ -509,6 +597,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :minWidth "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :minWidth "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-w value}))))}
@ -524,6 +615,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :maxHeight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :maxHeight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-max-h value}))))}
@ -539,5 +633,8 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :minHeight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :minHeight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout-child #{id} {:layout-item-min-h value}))))}))

View File

@ -60,6 +60,9 @@
(not (r/check-permission (obj/get text "$plugin") "content:write"))
(u/not-valid plugin-id :applyToText "Plugin doesn't have 'content:write' permission")
(not (u/page-active? (obj/get text "$page")))
(u/not-valid plugin-id :applyToText "Cannot modify a page that is not currently active")
:else
(let [id (obj/get text "$id")
values {:font-id id
@ -78,6 +81,9 @@
(not (r/check-permission (obj/get range "$plugin") "content:write"))
(u/not-valid plugin-id :applyToRange "Plugin doesn't have 'content:write' permission")
(not (u/page-active? (obj/get range "$page")))
(u/not-valid plugin-id :applyToRange "Cannot modify a page that is not currently active")
:else
(let [id (obj/get range "$id")
start (obj/get range "start")

View File

@ -45,6 +45,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :dir "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :dir "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-grid-dir value})))))}
@ -69,6 +72,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignItems "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignItems "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-align-items value})))))}
@ -85,6 +91,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignContent "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignContent "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-align-content value})))))}
@ -101,6 +110,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :justifyItems "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :justifyItems "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-justify-items value})))))}
@ -117,6 +129,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :justifyContent "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :justifyContent "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-justify-content value})))))}
@ -132,6 +147,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rowGap "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rowGap "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:row-gap value}}))))}
@ -147,6 +165,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :columnGap "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :columnGap "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-gap {:column-gap value}}))))}
@ -162,6 +183,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value :p3 value}}))))}
@ -177,6 +201,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value :p4 value}}))))}
@ -192,6 +219,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :topPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :topPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p1 value}}))))}
@ -207,6 +237,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :righPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :righPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p2 value}}))))}
@ -222,6 +255,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :bottomPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :bottomPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p3 value}}))))}
@ -237,6 +273,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :leftPadding "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :leftPadding "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-padding {:p4 value}}))))}
@ -254,6 +293,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addRow "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addRow "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/add-layout-track #{id} :row {:type type :value value})))))
@ -274,6 +316,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addRowAtIndex "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addRowAtIndex "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/add-layout-track #{id} :row {:type type :value value} index)))))
@ -291,6 +336,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addColumn "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addColumn "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/add-layout-track #{id} :column {:type type :value value})))))
@ -310,6 +358,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addColumnAtIndex "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addColumnAtIndex "Cannot modify a page that is not currently active")
:else
(let [type (keyword type)]
(st/emit! (dwsl/add-layout-track #{id} :column {:type type :value value} index)))))
@ -323,6 +374,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :removeRow "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :removeRow "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/remove-layout-track #{id} :row index))))
@ -335,6 +389,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :removeColumn "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :removeColumn "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/remove-layout-track #{id} :column index))))
@ -355,6 +412,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :setColumn "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :setColumn "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/change-layout-track #{id} :column index (d/without-nils {:type type :value value}))))))
@ -375,6 +435,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :setRow "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :setRow "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/change-layout-track #{id} :row index (d/without-nils {:type type :value value}))))))
@ -384,6 +447,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :remove "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :remove "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/remove-layout #{id}))))
@ -402,6 +468,10 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :appendChild "Plugin doesn't have 'content:write' permission")
(or (not (u/page-active? page-id))
(not (u/page-active? (obj/get child "$page"))))
(u/not-valid plugin-id :appendChild "Cannot modify a page that is not currently active")
:else
(let [child-id (obj/get child "$id")]
(st/emit! (dwt/move-shapes-to-frame #{child-id} id nil [row column])
@ -440,6 +510,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :row "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :row "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row value})))))}
@ -460,6 +533,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rowSpan "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rowSpan "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:row-span value})))))}
@ -480,6 +556,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :column "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :column "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column value})))))}
@ -500,6 +579,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :columnSpan "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :columnSpan "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cell-position (:parent-id shape) (:id cell) {:column-span value})))))}
@ -520,6 +602,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :areaName "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :areaName "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:area-name value})))))}
@ -541,6 +626,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :position "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :position "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/change-cells-mode (:parent-id shape) #{(:id cell)} value)))))}
@ -562,6 +650,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :alignSelf "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :alignSelf "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:align-self value})))))}
@ -583,5 +674,8 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :justifySelf "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :justifySelf "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-grid-cells (:parent-id shape) #{(:id cell)} {:justify-self value})))))})))

View File

@ -517,6 +517,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :applyToText "Plugin doesn't have 'content:write' permission")
(not (u/page-active? (obj/get shape "$page")))
(u/not-valid plugin-id :applyToText "Cannot modify a page that is not currently active")
:else
(let [shape-id (obj/get shape "$id")
typography (u/locate-library-typography file-id id)]
@ -531,6 +534,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :applyToText "Plugin doesn't have 'content:write' permission")
(not (u/page-active? (obj/get range "$page")))
(u/not-valid plugin-id :applyToText "Cannot modify a page that is not currently active")
:else
(let [shape-id (obj/get range "$id")
start (obj/get range "start")

View File

@ -330,6 +330,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addRulerGuide "Plugin doesn't have 'content:write' permission")
(not (u/page-active? id))
(u/not-valid plugin-id :addRulerGuide "Cannot modify a page that is not currently active")
:else
(let [ruler-id (uuid/next)]
(st/emit!
@ -351,6 +354,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :removeRulerGuide "Plugin doesn't have 'comment:write' permission")
(not (u/page-active? id))
(u/not-valid plugin-id :removeRulerGuide "Cannot modify a page that is not currently active")
:else
(let [guide (u/proxy->ruler-guide value)]
(st/emit! (-> (dwgu/remove-guide guide)

View File

@ -53,6 +53,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :board "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :board "Cannot modify a page that is not currently active")
:else
(let [board-id (when value (obj/get value "$id"))
guide (-> self u/proxy->ruler-guide)]
@ -85,6 +88,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :position "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :position "Cannot modify a page that is not currently active")
:else
(let [guide (u/proxy->ruler-guide self)
position
@ -109,12 +115,20 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :color "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :color "Cannot modify a page that is not currently active")
:else
(let [guide (u/proxy->ruler-guide self)]
(st/emit! (dwgu/update-guides (assoc guide :color value))))))}
:remove
(fn []
(let [guide (u/locate-ruler-guide file-id page-id id)]
(st/emit! (-> (dwgu/remove-guide guide)
(se/add-event plugin-id)))))))
(cond
(not (u/page-active? page-id))
(u/not-valid plugin-id :remove "Cannot modify a page that is not currently active")
:else
(let [guide (u/locate-ruler-guide file-id page-id id)]
(st/emit! (-> (dwgu/remove-guide guide)
(se/add-event plugin-id))))))))

View File

@ -196,6 +196,9 @@
(not (sm/validate [:vector types.fills/schema:fill] value))
(u/not-valid plugin-id :fills value)
(not (u/page-active? (obj/get self "$page")))
(u/not-valid plugin-id :fills "Cannot modify a page that is not currently active")
(cfh/text-shape? shape)
(st/emit! (dwt/update-attrs id {:fills value}))
@ -216,6 +219,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :strokes "Plugin doesn't have 'content:write' permission")
(not (u/page-active? (obj/get self "$page")))
(u/not-valid plugin-id :strokes "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :strokes value))))))
@ -268,6 +274,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :name "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :name "Cannot modify a page that is not currently active")
(not valid?)
(u/not-valid plugin-id :name value)
@ -286,6 +295,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :blocked "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :blocked "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dwsh/update-shapes [id] #(assoc % :blocked value))))))}
@ -302,6 +314,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :hidden "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :hidden "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dwsh/update-shapes [id] #(assoc % :hidden value))))))}
@ -318,6 +333,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :visible "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :visible "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dwsh/update-shapes [id] #(assoc % :hidden (not value)))))))}
@ -334,6 +352,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :proportionLock "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :proportionLock "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dwsh/update-shapes [id] #(assoc % :proportion-lock value))))))}
@ -352,6 +373,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :constraintsHorizontal "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :constraintsHorizontal "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :constraints-h value))))))}
@ -369,6 +393,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :constraintsVertical "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :constraintsVertical "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :constraints-v value))))))}
@ -385,6 +412,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :borderRadius "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :borderRadius "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(ctsr/set-radius-to-all-corners % value))))))}
@ -401,6 +431,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :borderRadiusTopLeft "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :borderRadiusTopLeft "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(ctsr/set-radius-to-single-corner % :r1 value))))))}
@ -417,6 +450,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :borderRadiusTopRight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :borderRadiusTopRight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(ctsr/set-radius-to-single-corner % :r2 value))))))}
@ -433,6 +469,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :borderRadiusBottomRight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :borderRadiusBottomRight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(ctsr/set-radius-to-single-corner % :r3 value))))))}
@ -449,6 +488,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :borderRadiusBottomLeft "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :borderRadiusBottomLeft "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(ctsr/set-radius-to-single-corner % :r4 value))))))}
@ -465,6 +507,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :opacity "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :opacity "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :opacity value))))))}
@ -482,6 +527,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :blendMode "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :blendMode "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :blend-mode value))))))}
@ -499,6 +547,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :shadows "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :shadows "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :shadow value))))))}
@ -519,6 +570,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :blur "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :blur "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :blur value)))))))}
@ -539,6 +593,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :background-blur "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :background-blur "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :background-blur value)))))))}
@ -556,6 +613,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :exports "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :exports "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :exports value))))))}
@ -573,6 +633,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :x "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :x "Cannot modify a page that is not currently active")
:else
(st/emit! (dw/update-position id
{:x value}
@ -591,6 +654,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :y "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :y "Cannot modify a page that is not currently active")
:else
(st/emit! (dw/update-position id
{:y value}
@ -636,6 +702,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :parentX "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :parentX "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")
parent-id (-> self u/proxy->shape :parent-id)
@ -663,6 +732,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :parentY "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :parentY "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")
parent-id (-> self u/proxy->shape :parent-id)
@ -690,6 +762,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :frameX "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :frameX "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")
frame-id (-> self u/proxy->shape :frame-id)
@ -717,6 +792,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :frameY "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :frameY "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")
frame-id (-> self u/proxy->shape :frame-id)
@ -754,6 +832,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rotation "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rotation "Cannot modify a page that is not currently active")
:else
(let [shape (u/proxy->shape self)]
(st/emit! (dw/increase-rotation #{(:id shape)} value)))))}
@ -770,6 +851,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :flipX "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :flipX "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dw/flip-horizontal-selected #{id})))))}
@ -786,6 +870,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :flipY "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :flipY "Cannot modify a page that is not currently active")
:else
(let [id (obj/get self "$id")]
(st/emit! (dw/flip-vertical-selected #{id})))))}
@ -853,6 +940,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :resize "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :resize "Cannot modify a page that is not currently active")
:else
(st/emit! (dw/update-dimensions [id] :width width)
(dw/update-dimensions [id] :height height))))
@ -870,6 +960,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :rotate "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :rotate "Cannot modify a page that is not currently active")
:else
(st/emit! (dw/increase-rotation [id] angle {:center center :delta? true})))))
@ -880,6 +973,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :clone "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :clone "Cannot modify a page that is not currently active")
:else
(do (st/emit! (dws/duplicate-shapes #{id} :change-selection? false :return-ref ret-v))
(shape-proxy plugin-id (deref ret-v))))))
@ -890,6 +986,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :remove "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :remove "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/delete-shapes #{id}))))
@ -916,6 +1015,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :setPluginData "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :setPluginData "Cannot modify a page that is not currently active")
:else
(st/emit! (dp/set-plugin-data file-id :shape id page-id (keyword "plugin" (str plugin-id)) key value))))
@ -952,6 +1054,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :setSharedPluginData "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :setSharedPluginData "Cannot modify a page that is not currently active")
:else
(st/emit! (dp/set-plugin-data file-id :shape id page-id (keyword "shared" namespace) key value))))
@ -1002,6 +1107,10 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :appendChild "Plugin doesn't have 'content:write' permission")
(or (not (u/page-active? page-id))
(not (u/page-active? (obj/get child "$page"))))
(u/not-valid plugin-id :appendChild "Cannot modify a page that is not currently active")
:else
(let [child-id (obj/get child "$id")
child-shape (u/locate-shape file-id page-id child-id)
@ -1032,6 +1141,10 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :insertChild "Plugin doesn't have 'content:write' permission")
(or (not (u/page-active? page-id))
(not (u/page-active? (obj/get child "$page"))))
(u/not-valid plugin-id :insertChild "Cannot modify a page that is not currently active")
:else
(let [child-id (obj/get child "$id")
child-shape (u/locate-shape file-id page-id child-id)
@ -1057,6 +1170,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addFlexLayout "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addFlexLayout "Cannot modify a page that is not currently active")
:else
(do (st/emit!
(dwsl/create-layout-from-id id :flex :from-frame? true :calculate-params? false)
@ -1073,6 +1189,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addGridLayout "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addGridLayout "Cannot modify a page that is not currently active")
:else
(do (st/emit! (dwsl/create-layout-from-id id :grid :from-frame? true :calculate-params? false))
(se/event plugin-id "create-shape-layout" :layout "grid")
@ -1089,6 +1208,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :makeMask "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :makeMask "Cannot modify a page that is not currently active")
:else
(st/emit!
(dwg/mask-group #{id})
@ -1104,6 +1226,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :removeMask "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :removeMask "Cannot modify a page that is not currently active")
:else
(st/emit! (dwg/unmask-group #{id})))))
@ -1148,6 +1273,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :applyTypography "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :applyTypography "Cannot modify a page that is not currently active")
:else
(let [typography (u/proxy->library-typography typography)]
(st/emit! (dwt/apply-typography #{id} typography file-id))))))
@ -1162,6 +1290,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :setParentIndex "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :setParentIndex "Cannot modify a page that is not currently active")
:else
(st/emit! (dw/set-shape-index file-id page-id id index))))
@ -1247,7 +1378,12 @@
:detach
(fn []
(st/emit! (dwl/detach-component id)))
(cond
(not (u/page-active? page-id))
(u/not-valid plugin-id :detach "Cannot modify a page that is not currently active")
:else
(st/emit! (dwl/detach-component id))))
;; Export
:export
@ -1363,6 +1499,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :addRulerGuide "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :addRulerGuide "Cannot modify a page that is not currently active")
:else
(let [ruler-id (uuid/next)
axis (parser/orientation->axis orientation)
@ -1388,6 +1527,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :removeRulerGuide "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :removeRulerGuide "Cannot modify a page that is not currently active")
:else
(let [guide (u/proxy->ruler-guide value)]
(st/emit! (-> (dwgu/remove-guide guide)
@ -1494,6 +1636,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :children "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :children "Cannot modify a page that is not currently active")
(not (every? shape-proxy? children))
(u/not-valid plugin-id :children "Every children needs to be shape proxies")
@ -1527,6 +1672,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :clipContent "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :clipContent "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :show-content (not value))))))}
@ -1543,6 +1691,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :showInViewMode "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :showInViewMode "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :hide-in-viewer (not value))))))}
@ -1578,6 +1729,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :guides "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :guides "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsh/update-shapes [id] #(assoc % :grids value))))))}
@ -1603,6 +1757,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :horizontalSizing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :horizontalSizing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-item-h-sizing value})))))}
@ -1619,6 +1776,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalSizing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalSizing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwsl/update-layout #{id} {:layout-item-v-sizing value})))))}
@ -1643,6 +1803,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :content "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :content "Cannot modify a page that is not currently active")
(not (sm/validate path/schema:segments segments))
(u/not-valid plugin-id :content segments)
@ -1669,6 +1832,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :content "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :content "Cannot modify a page that is not currently active")
(not (cfh/path-shape? data))
(u/not-valid plugin-id :content-type type)

View File

@ -127,6 +127,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontId "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontId "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end (font-data font variant))))))}
@ -149,6 +152,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontFamily "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontFamily "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end (font-data font variant))))))}
@ -170,6 +176,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontVariantId "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontVariantId "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end (variant-data variant))))))}
@ -190,6 +199,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontSize "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontSize "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:font-size value})))))}
@ -217,6 +229,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontWeight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontWeight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end (variant-data variant))))))}
@ -243,6 +258,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontStyle "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontStyle "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end (variant-data variant))))))}
@ -263,6 +281,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :lineHeight "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :lineHeight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:line-height value})))))}
@ -277,12 +298,15 @@
(fn [_ value]
(let [value (str/trim (dm/str value))]
(cond
(or (empty? value) (re-matches letter-spacing-re value))
(or (not (string? value)) (not (re-matches letter-spacing-re value)))
(u/not-valid plugin-id :letterSpacing value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :letterSpacing "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :letterSpacing "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:letter-spacing value})))))}
@ -302,6 +326,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textTransform "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :textTransform "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:text-transform value}))))}
@ -315,12 +342,15 @@
:set
(fn [_ value]
(cond
(and (string? value) (re-matches text-decoration-re value))
(or (not (string? value)) (not (re-matches text-decoration-re value)))
(u/not-valid plugin-id :textDecoration value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textDecoration "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :textDecoration "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:text-decoration value}))))}
@ -334,12 +364,15 @@
:set
(fn [_ value]
(cond
(and (string? value) (re-matches text-direction-re value))
(or (not (string? value)) (not (re-matches text-direction-re value)))
(u/not-valid plugin-id :direction value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :direction "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :direction "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:direction value}))))}
@ -353,12 +386,15 @@
:set
(fn [_ value]
(cond
(and (string? value) (re-matches text-align-re value))
(or (not (string? value)) (not (re-matches text-align-re value)))
(u/not-valid plugin-id :align value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :align "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :align "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:text-align value}))))}
@ -379,6 +415,9 @@
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fills "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fills "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-text-range id start end {:fills value})))))}
@ -393,274 +432,320 @@
(defn add-text-props
[shape-proxy plugin-id]
(crc/add-properties!
shape-proxy
{:name "characters"
:get #(-> % u/proxy->shape :content txt/content->text)
:set
(fn [self value]
(let [id (obj/get self "$id")]
;; The user is currently editing the text. We need to update the
;; editor as well
(cond
(or (not (string? value)) (empty? value))
(u/not-valid plugin-id :characters value)
(let [page-id (obj/get shape-proxy "$page")]
(crc/add-properties!
shape-proxy
{:name "characters"
:get #(-> % u/proxy->shape :content txt/content->text)
:set
(fn [self value]
(let [id (obj/get self "$id")]
;; The user is currently editing the text. We need to update the
;; editor as well
(cond
(or (not (string? value)) (empty? value))
(u/not-valid plugin-id :characters value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :characters "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :characters "Plugin doesn't have 'content:write' permission")
(contains? (:workspace-editor-state @st/state) id)
(let [shape (u/proxy->shape self)
editor
(-> shape
(get :content)
(txt/change-text value)
ted/import-content
ted/create-editor-state)]
(st/emit! (dwt/update-editor-state shape editor)))
(not (u/page-active? page-id))
(u/not-valid plugin-id :characters "Cannot modify a page that is not currently active")
:else
(do
(st/emit! (dwsh/update-shapes [id] #(update % :content txt/change-text value)))
(when (features/active-feature? @st/state "render-wasm/v1")
(st/emit! (dwwt/resize-wasm-text-debounce id)))))))}
(contains? (:workspace-editor-state @st/state) id)
(let [shape (u/proxy->shape self)
editor
(-> shape
(get :content)
(txt/change-text value)
ted/import-content
ted/create-editor-state)]
(st/emit! (dwt/update-editor-state shape editor)))
{:name "growType"
:get #(-> % u/proxy->shape :grow-type d/name)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (keyword value)]
(cond
(not (contains? #{:auto-width :auto-height :fixed} value))
(u/not-valid plugin-id :growType value)
:else
(do
(st/emit! (dwsh/update-shapes [id] #(update % :content txt/change-text value)))
(when (features/active-feature? @st/state "render-wasm/v1")
(st/emit! (dwwt/resize-wasm-text-debounce id)))))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :growType "Plugin doesn't have 'content:write' permission")
{:name "growType"
:get #(-> % u/proxy->shape :grow-type d/name)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (keyword value)]
(cond
(not (contains? #{:auto-width :auto-height :fixed} value))
(u/not-valid plugin-id :growType value)
:else
(st/emit!
(dwsh/update-shapes [id] #(assoc % :grow-type value))
(when (features/active-feature? @st/state "render-wasm/v1")
(st/emit! (dwwt/resize-wasm-text-debounce id)))))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :growType "Plugin doesn't have 'content:write' permission")
{:name "fontId"
:get #(-> % u/proxy->shape text-props :font-id format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (when (string? value) (fonts/get-font-data value))
variant (fonts/get-default-variant font)]
(cond
(not font)
(u/not-valid plugin-id :fontId value)
(not (u/page-active? page-id))
(u/not-valid plugin-id :growType "Cannot modify a page that is not currently active")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontId "Plugin doesn't have 'content:write' permission")
:else
(st/emit!
(dwsh/update-shapes [id] #(assoc % :grow-type value))
(when (features/active-feature? @st/state "render-wasm/v1")
(st/emit! (dwwt/resize-wasm-text-debounce id)))))))}
:else
(st/emit! (dwt/update-attrs id (font-data font variant))))))}
{:name "fontId"
:get #(-> % u/proxy->shape text-props :font-id format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (when (string? value) (fonts/get-font-data value))
variant (fonts/get-default-variant font)]
(cond
(not font)
(u/not-valid plugin-id :fontId value)
{:name "fontFamily"
:get #(-> % u/proxy->shape text-props :font-family format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/find-font-data {:family value})
variant (fonts/get-default-variant font)]
(cond
(not font)
(u/not-valid plugin-id :fontFamily value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontId "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontFamily "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontId "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id (font-data font variant))))))}
:else
(st/emit! (dwt/update-attrs id (font-data font variant))))))}
{:name "fontVariantId"
:get #(-> % u/proxy->shape text-props :font-variant-id format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
variant (fonts/get-variant font value)]
(cond
(not variant)
(u/not-valid plugin-id :fontVariantId value)
{:name "fontFamily"
:get #(-> % u/proxy->shape text-props :font-family format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/find-font-data {:family value})
variant (fonts/get-default-variant font)]
(cond
(not font)
(u/not-valid plugin-id :fontFamily value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontVariantId "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontFamily "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontFamily "Cannot modify a page that is not currently active")
{:name "fontSize"
:get #(-> % u/proxy->shape text-props :font-size format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (empty? value) (not (re-matches font-size-re value)))
(u/not-valid plugin-id :fontSize value)
:else
(st/emit! (dwt/update-attrs id (font-data font variant))))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontSize "Plugin doesn't have 'content:write' permission")
{:name "fontVariantId"
:get #(-> % u/proxy->shape text-props :font-variant-id format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
variant (fonts/get-variant font value)]
(cond
(not variant)
(u/not-valid plugin-id :fontVariantId value)
:else
(st/emit! (dwt/update-attrs id {:font-size value})))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontVariantId "Plugin doesn't have 'content:write' permission")
{:name "fontWeight"
:get #(-> % u/proxy->shape text-props :font-weight format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
weight (dm/str value)
style (obj/get self "fontStyle")
variant
(or
(fonts/find-variant font {:style style :weight weight})
(fonts/find-variant font {:weight weight}))]
(cond
(nil? variant)
(u/not-valid plugin-id :fontWeight (dm/str "Font weight '" value "' not supported for the current font"))
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontVariantId "Cannot modify a page that is not currently active")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontWeight "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
{:name "fontSize"
:get #(-> % u/proxy->shape text-props :font-size format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (empty? value) (not (re-matches font-size-re value)))
(u/not-valid plugin-id :fontSize value)
{:name "fontStyle"
:get #(-> % u/proxy->shape text-props :font-style format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
style (dm/str value)
weight (obj/get self "fontWeight")
variant
(or
(fonts/find-variant font {:weight weight :style style})
(fonts/find-variant font {:style style}))]
(cond
(nil? variant)
(u/not-valid plugin-id :fontStyle (dm/str "Font style '" value "' not supported for the current font"))
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontSize "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontStyle "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontSize "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
:else
(st/emit! (dwt/update-attrs id {:font-size value})))))}
{:name "lineHeight"
:get #(-> % u/proxy->shape text-props :line-height format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (empty? value) (not (re-matches line-height-re value)))
(u/not-valid plugin-id :lineHeight value)
{:name "fontWeight"
:get #(-> % u/proxy->shape text-props :font-weight format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
weight (dm/str value)
style (obj/get self "fontStyle")
variant
(or
(fonts/find-variant font {:style style :weight weight})
(fonts/find-variant font {:weight weight}))]
(cond
(nil? variant)
(u/not-valid plugin-id :fontWeight (dm/str "Font weight '" value "' not supported for the current font"))
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :lineHeight "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontWeight "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id {:line-height value})))))}
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontWeight "Cannot modify a page that is not currently active")
{:name "letterSpacing"
:get #(-> % u/proxy->shape text-props :letter-spacing format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (not (string? value)) (not (re-matches letter-spacing-re value)))
(u/not-valid plugin-id :letterSpacing value)
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :letterSpacing "Plugin doesn't have 'content:write' permission")
{:name "fontStyle"
:get #(-> % u/proxy->shape text-props :font-style format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
font (fonts/get-font-data (obj/get self "fontId"))
style (dm/str value)
weight (obj/get self "fontWeight")
variant
(or
(fonts/find-variant font {:weight weight :style style})
(fonts/find-variant font {:style style}))]
(cond
(nil? variant)
(u/not-valid plugin-id :fontStyle (dm/str "Font style '" value "' not supported for the current font"))
:else
(st/emit! (dwt/update-attrs id {:letter-spacing value})))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :fontStyle "Plugin doesn't have 'content:write' permission")
{:name "textTransform"
:get #(-> % u/proxy->shape text-props :text-transform format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-transform-re value)))
(u/not-valid plugin-id :textTransform value)
(not (u/page-active? page-id))
(u/not-valid plugin-id :fontStyle "Cannot modify a page that is not currently active")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textTransform "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id (variant-data variant))))))}
:else
(st/emit! (dwt/update-attrs id {:text-transform value})))))}
{:name "lineHeight"
:get #(-> % u/proxy->shape text-props :line-height format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (empty? value) (not (re-matches line-height-re value)))
(u/not-valid plugin-id :lineHeight value)
{:name "textDecoration"
:get #(-> % u/proxy->shape text-props :text-decoration format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-decoration-re value)))
(u/not-valid plugin-id :textDecoration value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :lineHeight "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textDecoration "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :lineHeight "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id {:text-decoration value})))))}
:else
(st/emit! (dwt/update-attrs id {:line-height value})))))}
{:name "direction"
:get #(-> % u/proxy->shape text-props :text-direction format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-direction-re value)))
(u/not-valid plugin-id :textDirection value)
{:name "letterSpacing"
:get #(-> % u/proxy->shape text-props :letter-spacing format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")
value (str/trim (dm/str value))]
(cond
(or (not (string? value)) (not (re-matches letter-spacing-re value)))
(u/not-valid plugin-id :letterSpacing value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textDirection "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :letterSpacing "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id {:text-direction value})))))}
(not (u/page-active? page-id))
(u/not-valid plugin-id :letterSpacing "Cannot modify a page that is not currently active")
{:name "align"
:get #(-> % u/proxy->shape text-props :text-align format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-align-re value)))
(u/not-valid plugin-id :align value)
:else
(st/emit! (dwt/update-attrs id {:letter-spacing value})))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :align "Plugin doesn't have 'content:write' permission")
{:name "textTransform"
:get #(-> % u/proxy->shape text-props :text-transform format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-transform-re value)))
(u/not-valid plugin-id :textTransform value)
:else
(st/emit! (dwt/update-attrs id {:text-align value})))))}
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textTransform "Plugin doesn't have 'content:write' permission")
{:name "verticalAlign"
:get #(-> % u/proxy->shape text-props :vertical-align)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches vertical-align-re value)))
(u/not-valid plugin-id :verticalAlign value)
(not (u/page-active? page-id))
(u/not-valid plugin-id :textTransform "Cannot modify a page that is not currently active")
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalAlign "Plugin doesn't have 'content:write' permission")
:else
(st/emit! (dwt/update-attrs id {:text-transform value})))))}
:else
(st/emit! (dwt/update-attrs id {:vertical-align value})))))}
{:name "textDecoration"
:get #(-> % u/proxy->shape text-props :text-decoration format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-decoration-re value)))
(u/not-valid plugin-id :textDecoration value)
{:name "textBounds"
:get #(-> % u/proxy->shape gst/shape->bounds format/format-geom-rect)}))
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textDecoration "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :textDecoration "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id {:text-decoration value})))))}
{:name "direction"
:get #(-> % u/proxy->shape text-props :text-direction format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-direction-re value)))
(u/not-valid plugin-id :textDirection value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :textDirection "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :textDirection "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id {:text-direction value})))))}
{:name "align"
:get #(-> % u/proxy->shape text-props :text-align format/format-mixed)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches text-align-re value)))
(u/not-valid plugin-id :align value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :align "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :align "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id {:text-align value})))))}
{:name "verticalAlign"
:get #(-> % u/proxy->shape text-props :vertical-align)
:set
(fn [self value]
(let [id (obj/get self "$id")]
(cond
(or (not (string? value)) (not (re-matches vertical-align-re value)))
(u/not-valid plugin-id :verticalAlign value)
(not (r/check-permission plugin-id "content:write"))
(u/not-valid plugin-id :verticalAlign "Plugin doesn't have 'content:write' permission")
(not (u/page-active? page-id))
(u/not-valid plugin-id :verticalAlign "Cannot modify a page that is not currently active")
:else
(st/emit! (dwt/update-attrs id {:vertical-align value})))))}
{:name "textBounds"
:get #(-> % u/proxy->shape gst/shape->bounds format/format-geom-rect)})))

View File

@ -43,6 +43,13 @@
(assert (uuid? id) "Shape not valid uuid")
(dm/get-in (locate-page file-id page-id) [:objects id]))
(defn page-active?
"Returns true if `page-id` is the currently active page. Plugin structural
operations only affect the active page, so callers use this to reject
attempts to modify shapes that live on a different page."
[page-id]
(= page-id (:current-page-id @st/state)))
(defn locate-library-color
[file-id id]
(assert (uuid? id) "Color not valid uuid")

View File

@ -0,0 +1,271 @@
;; 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 Sucursal en España SL
(ns frontend-tests.plugins.page-active-validation-test
"Tests for the guard that prevents plugins from modifying shapes/properties that
live on a page which is not the currently active one (see
`app.plugins.utils/page-active?`).
Strategy: build a rich page2 via the public API *while page2 is active*, then
enable `throwValidationErrors` so rejections surface as exceptions.
- Negative test: with page1 active, every guarded property/method invoked on a
page2-bound proxy must throw.
- Positive test: with page2 active, every setter (with a valid value) must NOT
throw. This proves the values used are valid, so the negative throws can only
come from the page guard."
(:require
[app.common.test-helpers.files :as cthf]
[app.main.store :as st]
[app.plugins.api :as api]
[app.util.object :as obj]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.state :as ths]
[frontend-tests.helpers.wasm :as thw]
[potok.v2.core :as ptk]))
(def ^:private plugin-id "00000000-0000-0000-0000-000000000000")
(defn- activate-page!
[store page-id]
(ptk/emit! store #(assoc % :current-page-id page-id)))
(defn- throws?
[thunk]
(try (thunk) false (catch :default _ true)))
(defn- setup
"Creates a file with two pages and builds, *on the non-active page2*, a set of
proxies covering every guarded proxy type. Leaves page1 active with the
`throwValidationErrors` flag enabled. Returns the proxies + store + page ids."
[]
(let [file (-> (cthf/sample-file :file1 :page-label :page1)
(cthf/add-sample-page :page2))
store (ths/setup-store file)
_ (set! st/state store)
_ (set! st/stream (ptk/input-stream store))
^js context (api/create-context plugin-id)
pages (.. context -currentFile -pages)
page1-id (obj/get (aget pages 0) "$id")
^js page2 (aget pages 1)
page2-id (obj/get page2 "$id")
;; Build everything with page2 active so the constructive API succeeds.
_ (activate-page! store page2-id)
^js rect (.createRectangle context)
^js rect2 (.createRectangle context)
^js board (.createBoard context)
^js child (.createRectangle context)
_ (.appendChild board child)
^js flex-board (.createBoard context)
^js flex (.addFlexLayout flex-board)
^js flex-child (.createRectangle context)
_ (.appendChild flex-board flex-child)
^js layout-child (.-layoutChild flex-child)
^js grid-board (.createBoard context)
^js grid (.addGridLayout grid-board)
^js text (.createText context "hello")
^js range (.getRange text 0 1)
^js guide (.addRulerGuide page2 "vertical" 10 board)
;; Back to page1: page2 proxies must now be read-only.
_ (activate-page! store page1-id)
_ (ptk/emit! store #(assoc-in % [:plugins :flags plugin-id :throw-validation-errors] true))]
{:store store :page1-id page1-id :page2-id page2-id :context context :page2 page2
:rect rect :rect2 rect2 :board board :child child
:flex flex :flex-board flex-board :layout-child layout-child :flex-child flex-child
:grid grid :grid-board grid-board
:text text :range range :guide guide}))
(defn- setter-specs
"Property setters (value mutations). Used by both the positive and negative
tests, so they must be idempotent / non-destructive."
[{:keys [^js rect ^js child ^js flex ^js grid ^js layout-child
^js range ^js guide ^js board ^js text]}]
[;; ---- ShapeProxy ----
["ShapeProxy.name" #(set! (.-name rect) "X")]
["ShapeProxy.x" #(set! (.-x rect) 10)]
["ShapeProxy.y" #(set! (.-y rect) 10)]
["ShapeProxy.blocked" #(set! (.-blocked rect) true)]
["ShapeProxy.hidden" #(set! (.-hidden rect) true)]
["ShapeProxy.visible" #(set! (.-visible rect) false)]
["ShapeProxy.proportionLock" #(set! (.-proportionLock rect) true)]
["ShapeProxy.constraintsHorizontal" #(set! (.-constraintsHorizontal rect) "right")]
["ShapeProxy.constraintsVertical" #(set! (.-constraintsVertical rect) "bottom")]
["ShapeProxy.borderRadius" #(set! (.-borderRadius rect) 5)]
["ShapeProxy.borderRadiusTopLeft" #(set! (.-borderRadiusTopLeft rect) 5)]
["ShapeProxy.borderRadiusTopRight" #(set! (.-borderRadiusTopRight rect) 5)]
["ShapeProxy.borderRadiusBottomRight" #(set! (.-borderRadiusBottomRight rect) 5)]
["ShapeProxy.borderRadiusBottomLeft" #(set! (.-borderRadiusBottomLeft rect) 5)]
["ShapeProxy.opacity" #(set! (.-opacity rect) 0.5)]
["ShapeProxy.blendMode" #(set! (.-blendMode rect) "multiply")]
["ShapeProxy.shadows" #(set! (.-shadows rect) #js [#js {:style "drop-shadow" :color #js {:color "#000000" :opacity 1}}])]
["ShapeProxy.blur" #(set! (.-blur rect) #js {:value 10})]
["ShapeProxy.exports" #(set! (.-exports rect) #js [#js {:type "png" :scale 1 :suffix ""}])]
["ShapeProxy.flipX" #(set! (.-flipX rect) true)]
["ShapeProxy.flipY" #(set! (.-flipY rect) true)]
["ShapeProxy.rotation" #(set! (.-rotation rect) 45)]
["ShapeProxy.fills" #(set! (.-fills rect) #js [#js {:fillColor "#fabada" :fillOpacity 1}])]
["ShapeProxy.strokes" #(set! (.-strokes rect) #js [#js {:strokeColor "#fabada" :strokeOpacity 1 :strokeWidth 2}])]
;; relative geometry (shape inside a board)
["ShapeProxy.boardX" #(set! (.-boardX child) 10)]
["ShapeProxy.boardY" #(set! (.-boardY child) 10)]
["ShapeProxy.parentX" #(set! (.-parentX child) 10)]
["ShapeProxy.parentY" #(set! (.-parentY child) 10)]
;; layout-item sizing (frame is a layout item)
["ShapeProxy.horizontalSizing" #(set! (.-horizontalSizing board) "fix")]
["ShapeProxy.verticalSizing" #(set! (.-verticalSizing board) "fix")]
;; text shape props (added via add-text-props)
["ShapeProxy.growType" #(set! (.-growType text) "fixed")]
["ShapeProxy.verticalAlign" #(set! (.-verticalAlign text) "center")]
;; ---- FlexLayoutProxy ----
["FlexLayoutProxy.dir" #(set! (.-dir flex) "row")]
["FlexLayoutProxy.wrap" #(set! (.-wrap flex) "wrap")]
["FlexLayoutProxy.alignItems" #(set! (.-alignItems flex) "center")]
["FlexLayoutProxy.alignContent" #(set! (.-alignContent flex) "center")]
["FlexLayoutProxy.justifyItems" #(set! (.-justifyItems flex) "start")]
["FlexLayoutProxy.justifyContent" #(set! (.-justifyContent flex) "center")]
["FlexLayoutProxy.rowGap" #(set! (.-rowGap flex) 5)]
["FlexLayoutProxy.columnGap" #(set! (.-columnGap flex) 5)]
["FlexLayoutProxy.verticalPadding" #(set! (.-verticalPadding flex) 5)]
["FlexLayoutProxy.horizontalPadding" #(set! (.-horizontalPadding flex) 5)]
["FlexLayoutProxy.topPadding" #(set! (.-topPadding flex) 5)]
["FlexLayoutProxy.rightPadding" #(set! (.-rightPadding flex) 5)]
["FlexLayoutProxy.bottomPadding" #(set! (.-bottomPadding flex) 5)]
["FlexLayoutProxy.leftPadding" #(set! (.-leftPadding flex) 5)]
;; ---- LayoutChildProxy ----
["LayoutChildProxy.absolute" #(set! (.-absolute layout-child) true)]
["LayoutChildProxy.zIndex" #(set! (.-zIndex layout-child) 1)]
["LayoutChildProxy.horizontalSizing" #(set! (.-horizontalSizing layout-child) "fix")]
["LayoutChildProxy.verticalSizing" #(set! (.-verticalSizing layout-child) "fix")]
["LayoutChildProxy.alignSelf" #(set! (.-alignSelf layout-child) "center")]
["LayoutChildProxy.horizontalMargin" #(set! (.-horizontalMargin layout-child) 5)]
["LayoutChildProxy.verticalMargin" #(set! (.-verticalMargin layout-child) 5)]
["LayoutChildProxy.topMargin" #(set! (.-topMargin layout-child) 5)]
["LayoutChildProxy.rightMargin" #(set! (.-rightMargin layout-child) 5)]
["LayoutChildProxy.bottomMargin" #(set! (.-bottomMargin layout-child) 5)]
["LayoutChildProxy.leftMargin" #(set! (.-leftMargin layout-child) 5)]
["LayoutChildProxy.maxWidth" #(set! (.-maxWidth layout-child) 100)]
["LayoutChildProxy.maxHeight" #(set! (.-maxHeight layout-child) 100)]
["LayoutChildProxy.minWidth" #(set! (.-minWidth layout-child) 0)]
["LayoutChildProxy.minHeight" #(set! (.-minHeight layout-child) 0)]
;; ---- GridLayoutProxy ----
["GridLayoutProxy.dir" #(set! (.-dir grid) "row")]
["GridLayoutProxy.alignItems" #(set! (.-alignItems grid) "center")]
["GridLayoutProxy.alignContent" #(set! (.-alignContent grid) "center")]
["GridLayoutProxy.justifyItems" #(set! (.-justifyItems grid) "start")]
["GridLayoutProxy.justifyContent" #(set! (.-justifyContent grid) "center")]
["GridLayoutProxy.rowGap" #(set! (.-rowGap grid) 5)]
["GridLayoutProxy.columnGap" #(set! (.-columnGap grid) 5)]
["GridLayoutProxy.verticalPadding" #(set! (.-verticalPadding grid) 5)]
["GridLayoutProxy.horizontalPadding" #(set! (.-horizontalPadding grid) 5)]
["GridLayoutProxy.topPadding" #(set! (.-topPadding grid) 5)]
["GridLayoutProxy.rightPadding" #(set! (.-rightPadding grid) 5)]
["GridLayoutProxy.bottomPadding" #(set! (.-bottomPadding grid) 5)]
["GridLayoutProxy.leftPadding" #(set! (.-leftPadding grid) 5)]
;; NOTE: GridCellProxy setters (row/column/rowSpan/columnSpan/areaName/position/
;; justifySelf/alignSelf) share the identical guard but require a child placed in
;; a grid cell, which cannot be fixtured in this headless test env
;; (move-shapes-to-frame is WASM-bound). They are verified by source review.
;; ---- TextRangeProxy ----
["TextRangeProxy.align" #(set! (.-align range) "center")]
["TextRangeProxy.direction" #(set! (.-direction range) "ltr")]
["TextRangeProxy.textTransform" #(set! (.-textTransform range) "uppercase")]
["TextRangeProxy.textDecoration" #(set! (.-textDecoration range) "underline")]
["TextRangeProxy.fontSize" #(set! (.-fontSize range) "16")]
["TextRangeProxy.lineHeight" #(set! (.-lineHeight range) "1.2")]
["TextRangeProxy.letterSpacing" #(set! (.-letterSpacing range) "1")]
["TextRangeProxy.fills" #(set! (.-fills range) #js [#js {:fillColor "#fabada" :fillOpacity 1}])]
;; ---- RulerGuideProxy ----
["RulerGuideProxy.board" #(set! (.-board guide) board)]
["RulerGuideProxy.color" #(set! (.-color guide) "#fabada")]
["RulerGuideProxy.position" #(set! (.-position guide) 20)]])
(defn- method-specs
"Structural / destructive methods. Tested in the negative direction only (they
are rejected before performing any mutation), with trivially valid arguments."
[{:keys [^js context ^js page2 ^js rect ^js rect2 ^js board ^js child
^js flex ^js grid ^js guide]}]
[;; ---- ShapeProxy ----
["ShapeProxy.resize" #(.resize rect 10 10)]
["ShapeProxy.rotate" #(.rotate rect 45)]
["ShapeProxy.clone" #(.clone rect)]
["ShapeProxy.remove" #(.remove rect)]
["ShapeProxy.setParentIndex" #(.setParentIndex child 0)]
["ShapeProxy.setPluginData" #(.setPluginData rect "k" "v")]
["ShapeProxy.setSharedPluginData" #(.setSharedPluginData rect "ns" "k" "v")]
["ShapeProxy.appendChild" #(.appendChild board rect)]
["ShapeProxy.insertChild" #(.insertChild board 0 rect)]
["ShapeProxy.addFlexLayout" #(.addFlexLayout board)]
["ShapeProxy.addGridLayout" #(.addGridLayout board)]
;; ---- FlexLayoutProxy ----
["FlexLayoutProxy.appendChild" #(.appendChild flex rect)]
;; ---- GridLayoutProxy ----
["GridLayoutProxy.appendChild" #(.appendChild grid rect 1 1)]
["GridLayoutProxy.addRow" #(.addRow grid "flex" 1)]
["GridLayoutProxy.addColumn" #(.addColumn grid "flex" 1)]
["GridLayoutProxy.addRowAtIndex" #(.addRowAtIndex grid 0 "flex" 1)]
["GridLayoutProxy.addColumnAtIndex" #(.addColumnAtIndex grid 0 "flex" 1)]
["GridLayoutProxy.setRow" #(.setRow grid 1 "flex" 1)]
["GridLayoutProxy.setColumn" #(.setColumn grid 1 "flex" 1)]
["GridLayoutProxy.removeRow" #(.removeRow grid 0)]
["GridLayoutProxy.removeColumn" #(.removeColumn grid 0)]
["GridLayoutProxy.remove" #(.remove grid)]
;; ---- GridCellProxy methods ----
;; (none beyond setters)
;; ---- RulerGuideProxy ----
["RulerGuideProxy.remove" #(.remove guide)]
;; ---- Context ----
["context.group" #(.group context #js [rect rect2])]
["context.ungroup" #(.ungroup context rect)]
["context.createBoolean" #(.createBoolean context "union" #js [rect rect2])]
;; ---- PageProxy ----
["page.addRulerGuide" #(.addRulerGuide page2 "vertical" 20 board)]
["page.removeRulerGuide" #(.removeRulerGuide page2 guide)]])
(t/deftest test-all-setters-rejected-on-non-active-page
(thw/with-wasm-mocks*
(fn []
(let [m (setup)]
(doseq [[label thunk] (setter-specs m)]
(t/is (throws? thunk) (str label " must be rejected on a non-active page")))))))
(t/deftest test-all-methods-rejected-on-non-active-page
(thw/with-wasm-mocks*
(fn []
(let [m (setup)]
(doseq [[label thunk] (method-specs m)]
(t/is (throws? thunk) (str label " must be rejected on a non-active page")))))))
(t/deftest test-all-setters-allowed-on-active-page
;; Sanity / value-validation anchor: every setter uses a valid value, so when
;; page2 is active none of them must throw. This guarantees the negative test's
;; throws come from the page guard and not from value validation.
(thw/with-wasm-mocks*
(fn []
(let [{:keys [store page2-id] :as m} (setup)]
(activate-page! store page2-id)
(doseq [[label thunk] (setter-specs m)]
(t/is (not (throws? thunk)) (str label " must be allowed on the active page")))))))

View File

@ -26,6 +26,7 @@
[frontend-tests.logic.pasting-in-containers-test]
[frontend-tests.main-errors-test]
[frontend-tests.plugins.context-shapes-test]
[frontend-tests.plugins.page-active-validation-test]
[frontend-tests.plugins.page-test]
[frontend-tests.plugins.parser-test]
[frontend-tests.plugins.tokens-test]
@ -77,6 +78,7 @@
frontend-tests.logic.groups-test
frontend-tests.logic.pasting-in-containers-test
frontend-tests.plugins.context-shapes-test
frontend-tests.plugins.page-active-validation-test
frontend-tests.plugins.page-test
frontend-tests.plugins.parser-test
frontend-tests.plugins.tokens-test

View File

@ -1,5 +1,7 @@
## 1.5.0 (Unreleased)
- **plugins-runtime**: changes outside the current page now raise a validation error when the target belongs to a page that is not currently active, instead of silently operating on the active page.
- **plugins-runtime**: Fix inverted validation that rejected valid values (and accepted invalid ones) on text range `align`, `direction`, `textDecoration`, `letterSpacing` and on layout child `zIndex`.
- **plugins-runtime**: Added `version` field that returns the current version
- **plugins-runtime**: Added optional parameter `throwOnError` to `penpot.ui.sendMessage` (default false, backwards-compatible)
- **plugin-types**: Added a flags subcontexts with the flag `naturalChildrenOrdering`

View File

@ -1263,12 +1263,30 @@ export interface Context {
openViewer(): void;
/**
* Creates a new page. Requires `content:write` permission.
* Creates a new page and returns it. Requires `content:write` permission.
*
* IMPORTANT: creating a page does **not** make it the active page.
* To build content inside the new page, activate it first with
* {@link Context.openPage} (and `await` it) before mutate shapes:
*
* @example
* ```js
* const page = penpot.createPage();
* page.name = 'New Page';
* await penpot.openPage(page); // make the new page active first
* const board = penpot.createBoard();
* board.resize(375, 812);
* page.root.appendChild(board);
* ```
*/
createPage(): Page;
/**
* Changes the current open page to given page. Requires `content:read` permission.
* Changes the current open page to the given page, making it the **active page**.
* The active page is the one all shape creation and structural operations
* (`createBoard`, `appendChild`, `insertChild`, property setters, etc.) act upon,
* so call this (and `await` it) after {@link Context.createPage} before adding
* shapes to the newly created page. Requires `content:read` permission.
* @param page the page to open (a Page object or a page UUID string)
* @param newWindow if true opens the page in a new window, defaults to false
*