mirror of
https://github.com/penpot/penpot.git
synced 2025-03-10 14:51:37 -05:00
🐛 Fix incorrect svg-attrs handlng on .zip import process
This commit is contained in:
parent
77472aabea
commit
b6c257bfc5
7 changed files with 56 additions and 92 deletions
|
@ -15,6 +15,7 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.pprint :as pp]
|
[app.common.pprint :as pp]
|
||||||
[app.common.schema :as sm]
|
[app.common.schema :as sm]
|
||||||
|
[app.common.svg :as csvg]
|
||||||
[app.common.types.components-list :as ctkl]
|
[app.common.types.components-list :as ctkl]
|
||||||
[app.common.types.container :as ctn]
|
[app.common.types.container :as ctn]
|
||||||
[app.common.types.file :as ctf]
|
[app.common.types.file :as ctf]
|
||||||
|
@ -300,9 +301,13 @@
|
||||||
(-> file
|
(-> file
|
||||||
(update :parent-stack pop))))
|
(update :parent-stack pop))))
|
||||||
|
|
||||||
(defn create-shape [file type data]
|
(defn create-shape
|
||||||
(let [obj (-> (cts/setup-shape (assoc data :type type))
|
[file type data]
|
||||||
|
(let [obj (-> (assoc data :type type)
|
||||||
|
(update :svg-attrs csvg/attrs->props)
|
||||||
|
(cts/setup-shape)
|
||||||
(check-name file :type))]
|
(check-name file :type))]
|
||||||
|
|
||||||
(-> file
|
(-> file
|
||||||
(commit-shape obj)
|
(commit-shape obj)
|
||||||
(assoc :last-id (:id obj))
|
(assoc :last-id (:id obj))
|
||||||
|
|
|
@ -608,12 +608,18 @@
|
||||||
(contains? svg-attr-list k)
|
(contains? svg-attr-list k)
|
||||||
(contains? svg-present-list k))
|
(contains? svg-present-list k))
|
||||||
(cond
|
(cond
|
||||||
|
(nil? v)
|
||||||
|
res
|
||||||
|
|
||||||
(= k :class)
|
(= k :class)
|
||||||
(assoc res :className v)
|
(assoc res :className v)
|
||||||
|
|
||||||
(= k :style)
|
(= k :style)
|
||||||
(let [v (if (string? v) (parse-style v) v)]
|
(let [v (if (string? v) (parse-style v) v)
|
||||||
(assoc res k (attrs->props v false)))
|
v (not-empty (attrs->props v false))]
|
||||||
|
(if v
|
||||||
|
(assoc res k v)
|
||||||
|
res))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(let [k (if (contains? non-react-props k)
|
(let [k (if (contains? non-react-props k)
|
||||||
|
@ -624,68 +630,6 @@
|
||||||
{}
|
{}
|
||||||
attrs)))
|
attrs)))
|
||||||
|
|
||||||
(defn clean-attrs
|
|
||||||
"Transforms attributes to their react equivalent
|
|
||||||
|
|
||||||
DEPRECATED: replaced by attrs->props"
|
|
||||||
([attrs]
|
|
||||||
(clean-attrs attrs true))
|
|
||||||
|
|
||||||
([attrs whitelist?]
|
|
||||||
(letfn [(known-property? [[key _]]
|
|
||||||
(or (not whitelist?)
|
|
||||||
(contains? svg-attr-list key)
|
|
||||||
(contains? svg-present-list key)))
|
|
||||||
|
|
||||||
(camelize [s]
|
|
||||||
(when (string? s)
|
|
||||||
#?(:cljs (js* "~{}.replace(\":\", \"-\").replace(/-./g, x=>x[1].toUpperCase())", s)
|
|
||||||
:clj (str/camel s))))
|
|
||||||
|
|
||||||
(transform-key [key]
|
|
||||||
(if (contains? non-react-props key)
|
|
||||||
key
|
|
||||||
(-> (d/name key)
|
|
||||||
(camelize)
|
|
||||||
(keyword))))
|
|
||||||
|
|
||||||
(format-styles [style-str]
|
|
||||||
(->> (str/split style-str ";")
|
|
||||||
(map str/trim)
|
|
||||||
(map #(str/split % ":"))
|
|
||||||
(group-by first)
|
|
||||||
(map (fn [[key val]]
|
|
||||||
[(transform-key key)
|
|
||||||
(second (first val))]))
|
|
||||||
(into {})))
|
|
||||||
|
|
||||||
(clean-key [[key val]]
|
|
||||||
(let [key (keyword key)]
|
|
||||||
(cond
|
|
||||||
(= key :class)
|
|
||||||
[:className val]
|
|
||||||
|
|
||||||
(and (= key :style)
|
|
||||||
(string? val))
|
|
||||||
[key (format-styles val)]
|
|
||||||
|
|
||||||
(and (= key :style)
|
|
||||||
(map? val))
|
|
||||||
[key (clean-attrs val false)]
|
|
||||||
|
|
||||||
:else
|
|
||||||
[(transform-key key) val])))]
|
|
||||||
|
|
||||||
;; Removed this warning because slows a lot rendering with big svgs
|
|
||||||
#_(let [filtered-props (->> attrs (remove known-property?) (map first))]
|
|
||||||
(when (seq filtered-props)
|
|
||||||
(.warn js/console "Unknown properties: " (str/join ", " filtered-props))))
|
|
||||||
|
|
||||||
(into {}
|
|
||||||
(comp (filter known-property?)
|
|
||||||
(map clean-key))
|
|
||||||
attrs))))
|
|
||||||
|
|
||||||
(defn update-attr-ids
|
(defn update-attr-ids
|
||||||
"Replaces the ids inside a property"
|
"Replaces the ids inside a property"
|
||||||
[attrs replace-fn]
|
[attrs replace-fn]
|
||||||
|
@ -723,7 +667,8 @@
|
||||||
(reduce visit-node result (:content node))))]
|
(reduce visit-node result (:content node))))]
|
||||||
(visit-node {} content)))
|
(visit-node {} content)))
|
||||||
|
|
||||||
(defn extract-defs [{:keys [attrs] :as node}]
|
(defn extract-defs
|
||||||
|
[{:keys [attrs] :as node}]
|
||||||
(if-not (map? node)
|
(if-not (map? node)
|
||||||
[{} node]
|
[{} node]
|
||||||
|
|
||||||
|
@ -741,19 +686,22 @@
|
||||||
|
|
||||||
[node-defs node])))
|
[node-defs node])))
|
||||||
|
|
||||||
(defn find-attr-references [attrs]
|
(defn find-attr-references
|
||||||
|
[attrs]
|
||||||
(->> attrs
|
(->> attrs
|
||||||
(mapcat (fn [[_ attr-value]]
|
(mapcat (fn [[_ attr-value]]
|
||||||
(if (string? attr-value)
|
(if (string? attr-value)
|
||||||
(extract-ids attr-value)
|
(extract-ids attr-value)
|
||||||
(find-attr-references attr-value))))))
|
(find-attr-references attr-value))))))
|
||||||
|
|
||||||
(defn find-node-references [node]
|
(defn find-node-references
|
||||||
|
[node]
|
||||||
(let [current (->> (find-attr-references (:attrs node)) (into #{}))
|
(let [current (->> (find-attr-references (:attrs node)) (into #{}))
|
||||||
children (->> (:content node) (map find-node-references) (flatten) (into #{}))]
|
children (->> (:content node) (map find-node-references) (flatten) (into #{}))]
|
||||||
(vec (into current children))))
|
(vec (into current children))))
|
||||||
|
|
||||||
(defn find-def-references [defs references]
|
(defn find-def-references
|
||||||
|
[defs references]
|
||||||
(loop [result (into #{} references)
|
(loop [result (into #{} references)
|
||||||
checked? #{}
|
checked? #{}
|
||||||
to-check (first references)
|
to-check (first references)
|
||||||
|
@ -778,7 +726,8 @@
|
||||||
(first pending)
|
(first pending)
|
||||||
(rest pending))))))
|
(rest pending))))))
|
||||||
|
|
||||||
(defn svg-transform-matrix [shape]
|
(defn svg-transform-matrix
|
||||||
|
[shape]
|
||||||
(if (:svg-viewbox shape)
|
(if (:svg-viewbox shape)
|
||||||
(let [{svg-x :x
|
(let [{svg-x :x
|
||||||
svg-y :y
|
svg-y :y
|
||||||
|
@ -810,34 +759,39 @@
|
||||||
;; Transforms spec:
|
;; Transforms spec:
|
||||||
;; https://www.w3.org/TR/SVG11/single-page.html#coords-TransformAttribute
|
;; https://www.w3.org/TR/SVG11/single-page.html#coords-TransformAttribute
|
||||||
|
|
||||||
|
(defn format-translate-params
|
||||||
(defn format-translate-params [params]
|
[params]
|
||||||
(assert (or (= (count params) 1) (= (count params) 2)))
|
(assert (or (= (count params) 1) (= (count params) 2)))
|
||||||
(if (= (count params) 1)
|
(if (= (count params) 1)
|
||||||
[(gpt/point (nth params 0) 0)]
|
[(gpt/point (nth params 0) 0)]
|
||||||
[(gpt/point (nth params 0) (nth params 1))]))
|
[(gpt/point (nth params 0) (nth params 1))]))
|
||||||
|
|
||||||
(defn format-scale-params [params]
|
(defn format-scale-params
|
||||||
|
[params]
|
||||||
(assert (or (= (count params) 1) (= (count params) 2)))
|
(assert (or (= (count params) 1) (= (count params) 2)))
|
||||||
(if (= (count params) 1)
|
(if (= (count params) 1)
|
||||||
[(gpt/point (nth params 0))]
|
[(gpt/point (nth params 0))]
|
||||||
[(gpt/point (nth params 0) (nth params 1))]))
|
[(gpt/point (nth params 0) (nth params 1))]))
|
||||||
|
|
||||||
(defn format-rotate-params [params]
|
(defn format-rotate-params
|
||||||
|
[params]
|
||||||
(assert (or (= (count params) 1) (= (count params) 3)) (str "??" (count params)))
|
(assert (or (= (count params) 1) (= (count params) 3)) (str "??" (count params)))
|
||||||
(if (= (count params) 1)
|
(if (= (count params) 1)
|
||||||
[(nth params 0) (gpt/point 0 0)]
|
[(nth params 0) (gpt/point 0 0)]
|
||||||
[(nth params 0) (gpt/point (nth params 1) (nth params 2))]))
|
[(nth params 0) (gpt/point (nth params 1) (nth params 2))]))
|
||||||
|
|
||||||
(defn format-skew-x-params [params]
|
(defn format-skew-x-params
|
||||||
|
[params]
|
||||||
(assert (= (count params) 1))
|
(assert (= (count params) 1))
|
||||||
[(nth params 0) 0])
|
[(nth params 0) 0])
|
||||||
|
|
||||||
(defn format-skew-y-params [params]
|
(defn format-skew-y-params
|
||||||
|
[params]
|
||||||
(assert (= (count params) 1))
|
(assert (= (count params) 1))
|
||||||
[0 (nth params 0)])
|
[0 (nth params 0)])
|
||||||
|
|
||||||
(defn to-matrix [{:keys [type params]}]
|
(defn to-matrix
|
||||||
|
[{:keys [type params]}]
|
||||||
(assert (#{"matrix" "translate" "scale" "rotate" "skewX" "skewY"} type))
|
(assert (#{"matrix" "translate" "scale" "rotate" "skewX" "skewY"} type))
|
||||||
(case type
|
(case type
|
||||||
"matrix" (apply gmt/matrix params)
|
"matrix" (apply gmt/matrix params)
|
||||||
|
@ -847,7 +801,8 @@
|
||||||
"skewX" (apply gmt/skew-matrix (format-skew-x-params params))
|
"skewX" (apply gmt/skew-matrix (format-skew-x-params params))
|
||||||
"skewY" (apply gmt/skew-matrix (format-skew-y-params params))))
|
"skewY" (apply gmt/skew-matrix (format-skew-y-params params))))
|
||||||
|
|
||||||
(defn parse-transform [transform-attr]
|
(defn parse-transform
|
||||||
|
[transform-attr]
|
||||||
(if transform-attr
|
(if transform-attr
|
||||||
(let [process-matrix
|
(let [process-matrix
|
||||||
(fn [[_ type params]]
|
(fn [[_ type params]]
|
||||||
|
@ -865,7 +820,8 @@
|
||||||
(defn format-move [[x y]] (str "M" x " " y))
|
(defn format-move [[x y]] (str "M" x " " y))
|
||||||
(defn format-line [[x y]] (str "L" x " " y))
|
(defn format-line [[x y]] (str "L" x " " y))
|
||||||
|
|
||||||
(defn points->path [points-str]
|
(defn points->path
|
||||||
|
[points-str]
|
||||||
(let [points (->> points-str
|
(let [points (->> points-str
|
||||||
(re-seq number-regex)
|
(re-seq number-regex)
|
||||||
(filter (comp not empty? first))
|
(filter (comp not empty? first))
|
||||||
|
|
|
@ -12,21 +12,21 @@
|
||||||
|
|
||||||
(t/deftest clean-attrs-1
|
(t/deftest clean-attrs-1
|
||||||
(let [attrs {:class "foobar"}
|
(let [attrs {:class "foobar"}
|
||||||
result (svg/clean-attrs attrs)]
|
result (svg/attrs->props attrs)]
|
||||||
(t/is (= result {:className "foobar"}))))
|
(t/is (= result {:className "foobar"}))))
|
||||||
|
|
||||||
(t/deftest clean-attrs-2
|
(t/deftest clean-attrs-2
|
||||||
(let [attrs {:overline-position "top"
|
(let [attrs {:overline-position "top"
|
||||||
:style {:fill "none"
|
:style {:fill "none"
|
||||||
:stroke-dashoffset 1}}
|
:stroke-dashoffset 1}}
|
||||||
result (svg/clean-attrs attrs true)]
|
result (svg/attrs->props attrs true)]
|
||||||
(t/is (= result {:overlinePosition "top", :style {:fill "none", :strokeDashoffset 1}}))))
|
(t/is (= result {:overlinePosition "top", :style {:fill "none", :strokeDashoffset 1}}))))
|
||||||
|
|
||||||
(t/deftest clean-attrs-3
|
(t/deftest clean-attrs-3
|
||||||
(let [attrs {:overline-position "top"
|
(let [attrs {:overline-position "top"
|
||||||
:style (str "fill:#00801b;fill-opacity:1;stroke:none;stroke-width:2749.72;"
|
:style (str "fill:#00801b;fill-opacity:1;stroke:none;stroke-width:2749.72;"
|
||||||
"stroke-linecap:round;stroke-dasharray:none;stop-color:#000000")}
|
"stroke-linecap:round;stroke-dasharray:none;stop-color:#000000")}
|
||||||
result (svg/clean-attrs attrs true)]
|
result (svg/attrs->props attrs true)]
|
||||||
(t/is (= result {:overlinePosition "top",
|
(t/is (= result {:overlinePosition "top",
|
||||||
:style {:fill "#00801b",
|
:style {:fill "#00801b",
|
||||||
:fillOpacity "1",
|
:fillOpacity "1",
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
(map? node)
|
(map? node)
|
||||||
[:> (d/name tag) (clj->js (csvg/clean-attrs attrs))
|
[:> (d/name tag) (obj/map->obj (csvg/attrs->props attrs))
|
||||||
(for [child content]
|
(for [child content]
|
||||||
[:& render-xml {:xml child :key (swap! internal-counter inc)}])]
|
[:& render-xml {:xml child :key (swap! internal-counter inc)}])]
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.geom.shapes.bounds :as gsb]
|
[app.common.geom.shapes.bounds :as gsb]
|
||||||
[app.common.svg :as csvg]
|
[app.common.svg :as csvg]
|
||||||
|
[app.util.object :as obj]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
(defn add-matrix [attrs transform-key transform-matrix]
|
(defn add-matrix [attrs transform-key transform-matrix]
|
||||||
|
@ -23,7 +24,9 @@
|
||||||
(str transform-matrix " " val)
|
(str transform-matrix " " val)
|
||||||
(str transform-matrix)))))
|
(str transform-matrix)))))
|
||||||
|
|
||||||
(mf/defc svg-node [{:keys [type node prefix-id transform bounds]}]
|
(mf/defc svg-node
|
||||||
|
{::mf/wrap-props false}
|
||||||
|
[{:keys [type node prefix-id transform bounds]}]
|
||||||
(cond
|
(cond
|
||||||
(string? node) node
|
(string? node) node
|
||||||
|
|
||||||
|
@ -48,7 +51,7 @@
|
||||||
attrs
|
attrs
|
||||||
(-> attrs
|
(-> attrs
|
||||||
(csvg/update-attr-ids prefix-id)
|
(csvg/update-attr-ids prefix-id)
|
||||||
(csvg/clean-attrs)
|
(csvg/attrs->props)
|
||||||
;; This clasname will be used to change the transform on the viewport
|
;; This clasname will be used to change the transform on the viewport
|
||||||
;; only necessary for groups because shapes have their own transform
|
;; only necessary for groups because shapes have their own transform
|
||||||
(cond-> (and (or transform-gradient?
|
(cond-> (and (or transform-gradient?
|
||||||
|
@ -80,7 +83,7 @@
|
||||||
:transform (str transform)}]
|
:transform (str transform)}]
|
||||||
[mf/Fragment #js {}])]
|
[mf/Fragment #js {}])]
|
||||||
|
|
||||||
[:> (name tag) (clj->js attrs)
|
[:> (name tag) (obj/map->obj attrs)
|
||||||
[:> wrapper wrapper-props
|
[:> wrapper wrapper-props
|
||||||
(for [[index node] (d/enumerate content)]
|
(for [[index node] (d/enumerate content)]
|
||||||
[:& svg-node {:key (dm/str "node-" index)
|
[:& svg-node {:key (dm/str "node-" index)
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
[app.common.geom.shapes :as gsh]
|
[app.common.geom.shapes :as gsh]
|
||||||
[app.common.svg :as csvg]
|
[app.common.svg :as csvg]
|
||||||
[app.main.ui.context :as muc]
|
[app.main.ui.context :as muc]
|
||||||
[app.main.ui.shapes.attrs :as usa]
|
[app.main.ui.shapes.attrs :as attrs]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
props (mf/with-memo [shape render-id]
|
props (mf/with-memo [shape render-id]
|
||||||
(-> #js {}
|
(-> #js {}
|
||||||
(usa/add-fill-props! shape render-id)
|
(attrs/add-fill-props! shape render-id)
|
||||||
(obj/unset! "transform")
|
(obj/unset! "transform")
|
||||||
(obj/set! "x" x)
|
(obj/set! "x" x)
|
||||||
(obj/set! "y" y)
|
(obj/set! "y" y)
|
||||||
|
@ -79,8 +79,7 @@
|
||||||
props
|
props
|
||||||
(mf/with-memo [shape render-id]
|
(mf/with-memo [shape render-id]
|
||||||
(let [element-id (dm/get-in shape [:svg-attrs :id])
|
(let [element-id (dm/get-in shape [:svg-attrs :id])
|
||||||
props (-> #js {}
|
props (attrs/add-fill-props! #js {} shape render-id)]
|
||||||
(usa/add-fill-props! shape render-id))]
|
|
||||||
|
|
||||||
(when (and (some? element-id)
|
(when (and (some? element-id)
|
||||||
(contains? ids-mapping element-id))
|
(contains? ids-mapping element-id))
|
||||||
|
|
|
@ -199,7 +199,8 @@
|
||||||
(rx/tap #(progress! context :upload-media name))
|
(rx/tap #(progress! context :upload-media name))
|
||||||
(rx/merge-map #(rp/cmd! :upload-file-media-object %))))
|
(rx/merge-map #(rp/cmd! :upload-file-media-object %))))
|
||||||
|
|
||||||
(defn resolve-text-content [node context]
|
(defn resolve-text-content
|
||||||
|
[node context]
|
||||||
(let [resolve (:resolve context)]
|
(let [resolve (:resolve context)]
|
||||||
(->> node
|
(->> node
|
||||||
(ct/transform-nodes
|
(ct/transform-nodes
|
||||||
|
|
Loading…
Add table
Reference in a new issue