mirror of
https://github.com/penpot/penpot.git
synced 2026-02-17 01:54:43 -05:00
Compare commits
12 Commits
2.14.0-RC1
...
staging
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
166dc05ff2 | ||
|
|
619e2387dc | ||
|
|
813c804d45 | ||
|
|
63f0c68977 | ||
|
|
1f2a234458 | ||
|
|
b281870c50 | ||
|
|
3909bc0fc1 | ||
|
|
b6427ecaac | ||
|
|
e82319c49e | ||
|
|
ce63bae92d | ||
|
|
1349789a7b | ||
|
|
d7203ef24c |
@@ -35,12 +35,18 @@
|
||||
- Fix viewer can update library [Taiga #13186](https://tree.taiga.io/project/penpot/issue/13186)
|
||||
- Fix remove fill affects different element than selected [Taiga #13128](https://tree.taiga.io/project/penpot/issue/13128)
|
||||
|
||||
## 2.13.3
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Revert yetti (http server) update, because that caused a regression on multipart uploads
|
||||
|
||||
## 2.13.2
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix modifying shapes by apply negative tokens to border radius [Taiga #13317](https://tree.taiga.io/project/penpot/issue/13317)
|
||||
- Fix security issue (Path Traversal Vulnerability) on fonts related RPC method
|
||||
- Fix arbitrary file read security issue on create-font-variant rpc method (https://github.com/penpot/penpot/security/advisories/GHSA-xp3f-g8rq-9px2)
|
||||
|
||||
|
||||
## 2.13.1
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
com.google.guava/guava {:mvn/version "33.4.8-jre"}
|
||||
|
||||
funcool/yetti
|
||||
{:git/tag "v11.9"
|
||||
:git/sha "5fad7a9"
|
||||
{:git/tag "v11.8"
|
||||
:git/sha "1d1b33f"
|
||||
:git/url "https://github.com/funcool/yetti.git"
|
||||
:exclusions [org.slf4j/slf4j-api]}
|
||||
|
||||
|
||||
@@ -867,15 +867,15 @@
|
||||
:on-change on-change
|
||||
:name (dm/str "flex-align-items-" type)
|
||||
:options [{:id (dm/str "align-items-start-" type)
|
||||
:icon (get-layout-flex-icon :align-items :start is-column)
|
||||
:icon (get-layout-grid-icon :align-items :start is-column)
|
||||
:label "Align items start"
|
||||
:value "start"}
|
||||
{:id (dm/str "align-items-center-" type)
|
||||
:icon (get-layout-flex-icon :align-items :center is-column)
|
||||
:icon (get-layout-grid-icon :align-items :center is-column)
|
||||
:label "Align items center"
|
||||
:value "center"}
|
||||
{:id (dm/str "align-items-end-" type)
|
||||
:icon (get-layout-flex-icon :align-items :end is-column)
|
||||
:icon (get-layout-grid-icon :align-items :end is-column)
|
||||
:label "Align items end"
|
||||
:value "end"}]}]))
|
||||
|
||||
|
||||
@@ -175,6 +175,10 @@
|
||||
(defn shape-proxy? [p]
|
||||
(obj/type-of? p "ShapeProxy"))
|
||||
|
||||
;; Cannot use token/token-proxy? here because of circular dependency in applyToShapes in token proxy
|
||||
(defn token-proxy? [t]
|
||||
(obj/type-of? t "TokenProxy"))
|
||||
|
||||
(defn shape-proxy
|
||||
([plugin-id id]
|
||||
(shape-proxy plugin-id (:current-file-id @st/state) (:current-page-id @st/state) id))
|
||||
@@ -1301,16 +1305,19 @@
|
||||
tokens)))}
|
||||
|
||||
:applyToken
|
||||
(fn [token attrs]
|
||||
(let [token (u/locate-token file-id (obj/get token "$set-id") (obj/get token "$id"))
|
||||
kw-attrs (into #{} (map keyword attrs))]
|
||||
(if (some #(not (cto/token-attr? %)) kw-attrs)
|
||||
(u/display-not-valid :applyToken attrs)
|
||||
(st/emit!
|
||||
(dwta/toggle-token {:token token
|
||||
:attrs kw-attrs
|
||||
:shape-ids [id]
|
||||
:expand-with-children false})))))
|
||||
{:schema [:tuple
|
||||
[:fn token-proxy?]
|
||||
[:maybe [:set [:and ::sm/keyword [:fn cto/token-attr?]]]]]
|
||||
:fn (fn [token attrs]
|
||||
(let [token (u/locate-token file-id (obj/get token "$set-id") (obj/get token "$id"))
|
||||
kw-attrs (into #{} (map keyword attrs))]
|
||||
(if (some #(not (cto/token-attr? %)) kw-attrs)
|
||||
(u/display-not-valid :applyToken attrs)
|
||||
(st/emit!
|
||||
(dwta/toggle-token {:token token
|
||||
:attrs kw-attrs
|
||||
:shape-ids [id]
|
||||
:expand-with-children false})))))}
|
||||
|
||||
:isVariantHead
|
||||
(fn []
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
[app.main.data.workspace.tokens.application :as dwta]
|
||||
[app.main.data.workspace.tokens.library-edit :as dwtl]
|
||||
[app.main.store :as st]
|
||||
;; [app.plugins.shape :as shape]
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
@@ -38,10 +37,14 @@
|
||||
(defn token-proxy? [p]
|
||||
(obj/type-of? p "TokenProxy"))
|
||||
|
||||
;; Cannot use shape/shape-proxy? here because of circular dependency in applyToken in shape proxy
|
||||
(defn shape-proxy? [s]
|
||||
(obj/type-of? s "ShapeProxy"))
|
||||
|
||||
(defn token-proxy
|
||||
[plugin-id file-id set-id id]
|
||||
(obj/reify {:name "TokenProxy"
|
||||
:wrap u/wrap-errors}
|
||||
:on-error u/handle-error}
|
||||
:$plugin {:enumerable false :get (constantly plugin-id)}
|
||||
:$file-id {:enumerable false :get (constantly file-id)}
|
||||
:$set-id {:enumerable false :get (constantly set-id)}
|
||||
@@ -113,14 +116,10 @@
|
||||
|
||||
:applyToShapes
|
||||
{:schema [:tuple
|
||||
;; FIXME: the schema decoder is interpreting the array of shape-proxys and converting
|
||||
;; them to plain maps. For now we adapt the schema to accept it, but the decoder
|
||||
;; should be fixed to keep the original proxy objects coming from the plugin.
|
||||
;; [:vector [:fn shape/shape-proxy?]]
|
||||
[:vector [:map [:id ::sm/uuid]]]
|
||||
[:maybe [:set [:set [:and ::sm/keyword [:fn cto/token-attr?]]]]]]
|
||||
[:vector [:fn shape-proxy?]]
|
||||
[:maybe [:set [:and ::sm/keyword [:fn cto/token-attr?]]]]]
|
||||
:fn (fn [shapes attrs]
|
||||
(apply-token-to-shapes file-id set-id id (map :id shapes) attrs))}
|
||||
(apply-token-to-shapes file-id set-id id (map #(obj/get % "$id") shapes) attrs))}
|
||||
|
||||
:applyToSelected
|
||||
{:schema [:tuple [:maybe [:set [:and ::sm/keyword [:fn cto/token-attr?]]]]]
|
||||
@@ -136,7 +135,7 @@
|
||||
(defn token-set-proxy
|
||||
[plugin-id file-id id]
|
||||
(obj/reify {:name "TokenSetProxy"
|
||||
:wrap u/wrap-errors}
|
||||
:on-error u/handle-error}
|
||||
:$plugin {:enumerable false :get (constantly plugin-id)}
|
||||
:$file-id {:enumerable false :get (constantly file-id)}
|
||||
:$id {:enumerable false :get (constantly id)}
|
||||
@@ -257,7 +256,7 @@
|
||||
(defn token-theme-proxy
|
||||
[plugin-id file-id id]
|
||||
(obj/reify {:name "TokenThemeProxy"
|
||||
:wrap u/wrap-errors}
|
||||
:on-error u/handle-error}
|
||||
:$plugin {:enumerable false :get (constantly plugin-id)}
|
||||
:$file-id {:enumerable false :get (constantly file-id)}
|
||||
:$id {:enumerable false :get (constantly id)}
|
||||
@@ -352,7 +351,7 @@
|
||||
(defn tokens-catalog
|
||||
[plugin-id file-id]
|
||||
(obj/reify {:name "TokensCatalog"
|
||||
:wrap u/wrap-errors}
|
||||
:on-error u/handle-error}
|
||||
:$plugin {:enumerable false :get (constantly plugin-id)}
|
||||
:$id {:enumerable false :get (constantly file-id)}
|
||||
|
||||
|
||||
@@ -223,7 +223,9 @@
|
||||
|
||||
(defn display-not-valid
|
||||
[code value]
|
||||
(.error js/console (dm/str "[PENPOT PLUGIN] Value not valid: " value ". Code: " code))
|
||||
(if (some? value)
|
||||
(.error js/console (dm/str "[PENPOT PLUGIN] Value not valid: " value ". Code: " code))
|
||||
(.error js/console (dm/str "[PENPOT PLUGIN] Value not valid. Code: " code)))
|
||||
nil)
|
||||
|
||||
(defn reject-not-valid
|
||||
@@ -248,19 +250,12 @@
|
||||
(let [s (set values)]
|
||||
(if (= (count s) 1) (first s) "mixed")))
|
||||
|
||||
(defn wrap-errors
|
||||
"Function wrapper to be used in plugin proxies methods to handle errors.
|
||||
When an exception is thrown, a readable error message is output to the console
|
||||
and the exception is captured."
|
||||
[f]
|
||||
(fn []
|
||||
(let [args (js-arguments)]
|
||||
(try
|
||||
(.apply f nil args)
|
||||
(catch :default cause
|
||||
(display-not-valid (ex-message cause) (obj/stringify args))
|
||||
(if-let [explain (-> cause ex-data ::sm/explain)]
|
||||
(println (sm/humanize-explain explain))
|
||||
(js/console.log (ex-data cause)))
|
||||
(js/console.log (.-stack cause))
|
||||
nil)))))
|
||||
(defn handle-error
|
||||
"Function to be used in plugin proxies methods to handle errors and print a readable
|
||||
message to the console."
|
||||
[cause]
|
||||
(display-not-valid (ex-message cause) nil)
|
||||
(if-let [explain (-> cause ex-data ::sm/explain)]
|
||||
(println (sm/humanize-explain explain))
|
||||
(js/console.log (ex-data cause)))
|
||||
(js/console.log (.-stack cause)))
|
||||
@@ -10,6 +10,7 @@
|
||||
(:refer-clojure :exclude [set! new get merge clone contains? array? into-array reify class])
|
||||
#?(:cljs (:require-macros [app.util.object]))
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.json :as json]
|
||||
[app.common.schema :as sm]
|
||||
[clojure.core :as c]
|
||||
@@ -156,6 +157,7 @@
|
||||
|
||||
this-sym (with-meta (gensym (str rsym "-this-")) {:tag 'js})
|
||||
target-sym (with-meta (gensym (str rsym "-target-")) {:tag 'js})
|
||||
cause-sym (gensym "cause-")
|
||||
|
||||
make-sym
|
||||
(fn [pname prefix]
|
||||
@@ -176,6 +178,7 @@
|
||||
wrap (c/get params :wrap)
|
||||
schema-1 (c/get params :schema-1)
|
||||
this? (c/get params :this false)
|
||||
on-error (c/get params :on-error)
|
||||
|
||||
decode-expr
|
||||
(c/get params :decode/fn)
|
||||
@@ -214,7 +217,16 @@
|
||||
(with-meta {:tag 'function}))
|
||||
|
||||
val-sym
|
||||
(gensym (str "val-" (str/slug pname) "-"))]
|
||||
(gensym (str "val-" (str/slug pname) "-"))
|
||||
|
||||
wrap-error-handling
|
||||
(if on-error
|
||||
(fn [expr]
|
||||
`(try
|
||||
~expr
|
||||
(catch :default ~cause-sym
|
||||
(~on-error ~cause-sym))))
|
||||
identity)]
|
||||
|
||||
(concat
|
||||
(when wrap
|
||||
@@ -226,8 +238,13 @@
|
||||
`(fn []
|
||||
(let [~this-sym (~'js* "this")
|
||||
~fn-sym ~get-expr]
|
||||
(.call ~fn-sym ~this-sym ~this-sym)))
|
||||
get-expr)])
|
||||
~(wrap-error-handling
|
||||
`(.call ~fn-sym ~this-sym ~this-sym))))
|
||||
`(fn []
|
||||
(let [~this-sym (~'js* "this")
|
||||
~fn-sym ~get-expr]
|
||||
~(wrap-error-handling
|
||||
`(.call ~fn-sym ~this-sym)))))])
|
||||
|
||||
(when set-expr
|
||||
[schema-sym schema-n
|
||||
@@ -241,28 +258,35 @@
|
||||
|
||||
(make-sym pname "set-fn")
|
||||
`(fn [~val-sym]
|
||||
(let [~this-sym (~'js* "this")
|
||||
~fn-sym ~set-expr
|
||||
~(wrap-error-handling
|
||||
`(let [~this-sym (~'js* "this")
|
||||
~fn-sym ~set-expr
|
||||
|
||||
;; We only emit schema and coercer bindings if
|
||||
;; schema-n is provided
|
||||
~@(if (some? schema-n)
|
||||
[schema-sym `(if (fn? ~schema-sym)
|
||||
(~schema-sym ~val-sym)
|
||||
~schema-sym)
|
||||
;; We only emit schema and coercer bindings if
|
||||
;; schema-n is provided
|
||||
~@(if (some? schema-n)
|
||||
[schema-sym
|
||||
`(if (fn? ~schema-sym)
|
||||
(~schema-sym ~val-sym)
|
||||
~schema-sym)
|
||||
|
||||
coercer-sym `(if (nil? ~coercer-sym)
|
||||
(sm/coercer ~schema-sym)
|
||||
~coercer-sym)
|
||||
val-sym (if (not= decode-expr 'app.common.json/->clj)
|
||||
`(~decode-sym ~val-sym)
|
||||
`(~decode-sym ~val-sym ~decode-options))
|
||||
val-sym `(~coercer-sym ~val-sym)]
|
||||
[])]
|
||||
coercer-sym
|
||||
`(if (nil? ~coercer-sym)
|
||||
(sm/coercer ~schema-sym)
|
||||
~coercer-sym)
|
||||
|
||||
~(if this?
|
||||
`(.call ~fn-sym ~this-sym ~this-sym ~val-sym)
|
||||
`(.call ~fn-sym ~this-sym ~val-sym))))])
|
||||
val-sym
|
||||
(if (not= decode-expr 'app.common.json/->clj)
|
||||
`(~decode-sym ~val-sym)
|
||||
`(~decode-sym ~val-sym ~decode-options))
|
||||
|
||||
val-sym
|
||||
`(~coercer-sym ~val-sym)]
|
||||
[])]
|
||||
|
||||
~(if this?
|
||||
`(.call ~fn-sym ~this-sym ~this-sym ~val-sym)
|
||||
`(.call ~fn-sym ~this-sym ~val-sym)))))])
|
||||
|
||||
(when fn-expr
|
||||
[schema-sym (or schema-n schema-1)
|
||||
@@ -275,7 +299,12 @@
|
||||
(make-sym pname "get-fn")
|
||||
`(fn []
|
||||
(let [~this-sym (~'js* "this")
|
||||
~fn-sym ~fn-expr
|
||||
~fn-sym ~(if (and (list? fn-expr)
|
||||
(= 'fn (first fn-expr)))
|
||||
(let [[sa sb & sother] fn-expr]
|
||||
`(~sa ~sb ~(wrap-error-handling `(do ~@sother))))
|
||||
fn-expr)
|
||||
|
||||
~fn-sym ~(if this?
|
||||
`(.bind ~fn-sym ~this-sym ~this-sym)
|
||||
`(.bind ~fn-sym ~this-sym))
|
||||
@@ -284,25 +313,31 @@
|
||||
;; schema-n or schema-1 is provided
|
||||
~@(if (or schema-n schema-1)
|
||||
[fn-sym `(fn* [~@(if schema-1 [val-sym] [])]
|
||||
(let [~@(if schema-n
|
||||
[val-sym `(into-array (cljs.core/js-arguments))]
|
||||
[])
|
||||
~val-sym ~(if (not= decode-expr 'app.common.json/->clj)
|
||||
`(~decode-sym ~val-sym)
|
||||
`(~decode-sym ~val-sym ~decode-options))
|
||||
~(wrap-error-handling
|
||||
`(let [~@(if schema-n
|
||||
[val-sym `(into-array (cljs.core/js-arguments))]
|
||||
[])
|
||||
~val-sym
|
||||
~(if (not= decode-expr 'app.common.json/->clj)
|
||||
`(~decode-sym ~val-sym)
|
||||
`(~decode-sym ~val-sym ~decode-options))
|
||||
|
||||
~schema-sym (if (fn? ~schema-sym)
|
||||
(~schema-sym ~val-sym)
|
||||
~schema-sym)
|
||||
~schema-sym
|
||||
(if (fn? ~schema-sym)
|
||||
(~schema-sym ~val-sym)
|
||||
~schema-sym)
|
||||
|
||||
~coercer-sym (if (nil? ~coercer-sym)
|
||||
(sm/coercer ~schema-sym)
|
||||
~coercer-sym)
|
||||
~coercer-sym
|
||||
(if (nil? ~coercer-sym)
|
||||
(sm/coercer ~schema-sym)
|
||||
~coercer-sym)
|
||||
|
||||
~val-sym (~coercer-sym ~val-sym)]
|
||||
~(if schema-1
|
||||
`(~fn-sym ~val-sym)
|
||||
`(apply ~fn-sym ~val-sym))))]
|
||||
~val-sym
|
||||
(~coercer-sym ~val-sym)]
|
||||
|
||||
~(if schema-1
|
||||
`(~fn-sym ~val-sym)
|
||||
`(apply ~fn-sym ~val-sym)))))]
|
||||
[])]
|
||||
~(if wrap
|
||||
`(~wrap-sym ~fn-sym)
|
||||
@@ -375,12 +410,16 @@
|
||||
(let [definition (first params)]
|
||||
(if (some? definition)
|
||||
(let [definition (if (map? definition)
|
||||
(c/merge {:wrap (:wrap tmeta)} definition)
|
||||
(c/merge {:wrap (:wrap tmeta)
|
||||
:on-error (:on-error tmeta)}
|
||||
definition)
|
||||
(-> {:enumerable false}
|
||||
(c/merge (meta definition))
|
||||
(assoc :wrap (:wrap tmeta))
|
||||
(assoc :on-error (:on-error tmeta))
|
||||
(assoc :fn definition)
|
||||
(dissoc :get :set)))
|
||||
(dissoc :get :set :line :column)
|
||||
(d/without-nils)))
|
||||
definition (assoc definition :name (name ckey))]
|
||||
|
||||
(recur (rest params)
|
||||
|
||||
28
plugins/libs/plugin-types/index.d.ts
vendored
28
plugins/libs/plugin-types/index.d.ts
vendored
@@ -5226,27 +5226,27 @@ type TokenDimensionProps =
|
||||
/**
|
||||
* The properties that a FontFamilies token can be applied to.
|
||||
*/
|
||||
type TokenFontFamiliesProps = 'font-families';
|
||||
type TokenFontFamiliesProps = 'fontFamilies';
|
||||
|
||||
/**
|
||||
* The properties that a FontSizes token can be applied to.
|
||||
*/
|
||||
type TokenFontSizesProps = 'font-size';
|
||||
type TokenFontSizesProps = 'fontSize';
|
||||
|
||||
/**
|
||||
* The properties that a FontWeight token can be applied to.
|
||||
*/
|
||||
type TokenFontWeightProps = 'font-weight';
|
||||
type TokenFontWeightProps = 'fontWeight';
|
||||
|
||||
/**
|
||||
* The properties that a LetterSpacing token can be applied to.
|
||||
*/
|
||||
type TokenLetterSpacingProps = 'letter-spacing';
|
||||
type TokenLetterSpacingProps = 'letterSpacing';
|
||||
|
||||
/**
|
||||
* The properties that a Number token can be applied to.
|
||||
*/
|
||||
type TokenNumberProps = 'rotation' | 'line-height';
|
||||
type TokenNumberProps = 'rotation';
|
||||
|
||||
/**
|
||||
* The properties that an Opacity token can be applied to.
|
||||
@@ -5262,18 +5262,18 @@ type TokenSizingProps =
|
||||
| 'height'
|
||||
|
||||
// Layout
|
||||
| 'layout-item-min-w'
|
||||
| 'layout-item-max-w'
|
||||
| 'layout-item-min-h'
|
||||
| 'layout-item-max-h';
|
||||
| 'layoutItemMinW'
|
||||
| 'layoutItemMaxW'
|
||||
| 'layoutItemMinH'
|
||||
| 'layoutItemMaxH';
|
||||
|
||||
/**
|
||||
* The properties that a Spacing token can be applied to.
|
||||
*/
|
||||
type TokenSpacingProps =
|
||||
// Spacing / Gap
|
||||
| 'row-gap'
|
||||
| 'column-gap'
|
||||
| 'rowGap'
|
||||
| 'columnGap'
|
||||
|
||||
// Spacing / Padding
|
||||
| 'p1'
|
||||
@@ -5290,17 +5290,17 @@ type TokenSpacingProps =
|
||||
/**
|
||||
* The properties that a BorderWidth token can be applied to.
|
||||
*/
|
||||
type TokenBorderWidthProps = 'stroke-width';
|
||||
type TokenBorderWidthProps = 'strokeWidth';
|
||||
|
||||
/**
|
||||
* The properties that a TextCase token can be applied to.
|
||||
*/
|
||||
type TokenTextCaseProps = 'text-case';
|
||||
type TokenTextCaseProps = 'textCase';
|
||||
|
||||
/**
|
||||
* The properties that a TextDecoration token can be applied to.
|
||||
*/
|
||||
type TokenTextDecorationProps = 'text-decoration';
|
||||
type TokenTextDecorationProps = 'textDecoration';
|
||||
|
||||
/**
|
||||
* The properties that a Typography token can be applied to.
|
||||
|
||||
Reference in New Issue
Block a user