0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 07:11:32 -05:00

🐛 Fix many issues svg/attrs->props function

This commit is contained in:
Andrey Antukh 2024-01-31 16:41:57 +01:00
parent 1de9171d50
commit 457feedec4
2 changed files with 93 additions and 91 deletions

View file

@ -35,8 +35,18 @@
(def tags-to-remove #{:linearGradient :radialGradient :metadata :mask :clipPath :filter :title})
(defn- camelize
[s]
(when (string? s)
(let [vendor? (str/starts-with? s "-")
result #?(:cljs (js* "~{}.replace(\":\", \"-\").replace(/-./g, x=>x[1].toUpperCase())", s)
:clj (str/camel s))]
(if ^boolean vendor?
(str/capital result)
result))))
;; https://www.w3.org/TR/SVG11/eltindex.html
(def svg-tags-list
(def svg-tags
#{:a
:altGlyph
:altGlyphDef
@ -118,7 +128,7 @@
:vkern})
;; https://www.w3.org/TR/SVG11/attindex.html
(def svg-attr-list
(def svg-attrs
#{:accent-height
:accumulate
:additive
@ -212,26 +222,6 @@
:name
:numOctaves
:offset
;; We don't support events
;;:onabort
;;:onactivate
;;:onbegin
;;:onclick
;;:onend
;;:onerror
;;:onfocusin
;;:onfocusout
;;:onload
;;:onmousedown
;;:onmousemove
;;:onmouseout
;;:onmouseover
;;:onmouseup
;;:onrepeat
;;:onresize
;;:onscroll
;;:onunload
;;:onzoom
:operator
:order
:orient
@ -336,7 +326,8 @@
:z
:zoomAndPan})
(def svg-present-list
(def svg-presentation-attrs
"A set of presentation SVG attributes as per SVG spec."
#{:alignment-baseline
:baseline-shift
:clip-path
@ -399,52 +390,52 @@
:mask-type})
(def inheritable-props
[:style
:clip-rule
:color
:color-interpolation
:color-interpolation-filters
:color-profile
:color-rendering
:cursor
:direction
:dominant-baseline
:fill
:fill-opacity
:fill-rule
:font
:font-family
:font-size
:font-size-adjust
:font-stretch
:font-style
:font-variant
:font-weight
:glyph-orientation-horizontal
:glyph-orientation-vertical
:image-rendering
:letter-spacing
:marker
:marker-end
:marker-mid
:marker-start
:paint-order
:pointer-events
:shape-rendering
:stroke
:stroke-dasharray
:stroke-dashoffset
:stroke-linecap
:stroke-linejoin
:stroke-miterlimit
:stroke-opacity
:stroke-width
:text-anchor
:text-rendering
:transform
:visibility
:word-spacing
:writing-mode])
#{:style
:clip-rule
:color
:color-interpolation
:color-interpolation-filters
:color-profile
:color-rendering
:cursor
:direction
:dominant-baseline
:fill
:fill-opacity
:fill-rule
:font
:font-family
:font-size
:font-size-adjust
:font-stretch
:font-style
:font-variant
:font-weight
:glyph-orientation-horizontal
:glyph-orientation-vertical
:image-rendering
:letter-spacing
:marker
:marker-end
:marker-mid
:marker-start
:paint-order
:pointer-events
:shape-rendering
:stroke
:stroke-dasharray
:stroke-dashoffset
:stroke-linecap
:stroke-linejoin
:stroke-miterlimit
:stroke-opacity
:stroke-width
:text-anchor
:text-rendering
:transform
:visibility
:word-spacing
:writing-mode})
(def gradient-tags
#{:linearGradient
@ -517,6 +508,29 @@
:text
:view})
(defn prop-key
"Convert an attr key to a react compatible prop key. Returns nil if key is empty or invalid"
[k]
(let [kn (cond
(string? k) k
(keyword? k) (name k))]
(case kn
("" nil) nil
"class" :className
"for" :htmlFor
(let [kn1 (subs kn 0 1)]
(if (= kn1 (str/upper kn1))
(-> kn camelize str/capital keyword)
(-> kn camelize keyword))))))
(def svg-props
"A set of all attrs (including the presentation) converted to
camelCase for make it React compatible."
(let [xf (map prop-key)]
(-> #{}
(into xf svg-attrs)
(into xf svg-presentation-attrs))))
;; Defaults for some tags per spec https://www.w3.org/TR/SVG11/single-page.html
;; they are basically the defaults that can be percents and we need to replace because
;; otherwise won't work as expected in the workspace
@ -560,16 +574,6 @@
:else
num-str))
(defn- camelize
[s]
(when (string? s)
(let [vendor? (str/starts-with? s "-")
result #?(:cljs (js* "~{}.replace(\":\", \"-\").replace(/-./g, x=>x[1].toUpperCase())", s)
:clj (str/camel s))]
(if ^boolean vendor?
(str/capital result)
result))))
(defn parse-style
[style]
(reduce (fn [res item]
@ -600,15 +604,13 @@
([attrs whitelist?]
(reduce-kv (fn [res k v]
(if (or (not whitelist?)
(contains? svg-attr-list k)
(contains? svg-present-list k))
(let [k (prop-key k)]
(cond
(nil? v)
(nil? k)
res
(= k :class)
(assoc res :className v)
(nil? v)
res
(= k :style)
(let [v (if (string? v) (parse-style v) v)
@ -618,10 +620,10 @@
res))
:else
(let [k (-> k d/name camelize keyword)]
(assoc res k v)))
res))
(if (or (not whitelist?) (contains? svg-props k))
(let [v (if (string? v) (str/trim v) v)]
(assoc res k v))
res))))
{}
attrs)))
@ -669,7 +671,7 @@
(let [remove-node? (fn [{:keys [tag]}] (and (some? tag)
(or (contains? tags-to-remove tag)
(not (contains? svg-tags-list tag)))))
(not (contains? svg-tags tag)))))
rec-result (->> (:content node) (map extract-defs))
node (assoc node :content (->> rec-result (map second) (filterv (comp not remove-node?))))

View file

@ -104,7 +104,7 @@
svg-root? (and (map? content) (= tag :svg))
svg-tag? (map? content)
svg-leaf? (string? content)
valid-tag? (contains? csvg/svg-tags-list tag)]
valid-tag? (contains? csvg/svg-tags tag)]
(cond
^boolean svg-root?