diff --git a/CHANGES.md b/CHANGES.md index d7443b8db..5ae7135d2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ ### :bug: Bugs fixed - Fix problem with rules position on changing pages [Taiga #4847](https://tree.taiga.io/project/penpot/issue/4847) +- Fix error streen when uploading wrong SVG [#2995](https://github.com/penpot/penpot/issues/2995) ### :arrow_up: Deps updates diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index e807d1937..5d9d911f8 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -62,7 +62,9 @@ height (get-in data [:attrs :height] 100) viewbox (get-in data [:attrs :viewBox] (str "0 0 " width " " height)) [x y width height] (->> (str/split viewbox #"\s+") - (map d/parse-double))] + (map d/parse-double)) + width (if (= width 0) 1 width) + height (if (= height 0) 1 height)] [(assert-valid-num :x x) (assert-valid-num :y y) (assert-valid-pos-num :width width) @@ -483,117 +485,118 @@ (defn create-svg-shapes [svg-data {:keys [x y]} objects frame-id parent-id selected center?] - (try - (let [[vb-x vb-y vb-width vb-height] (svg-dimensions svg-data) - x (mth/round - (if center? - (- x vb-x (/ vb-width 2)) - x)) - y (mth/round - (if center? - (- y vb-y (/ vb-height 2)) - y)) + (let [[vb-x vb-y vb-width vb-height] (svg-dimensions svg-data) + x (mth/round + (if center? + (- x vb-x (/ vb-width 2)) + x)) + y (mth/round + (if center? + (- y vb-y (/ vb-height 2)) + y)) - unames (cp/retrieve-used-names objects) + unames (cp/retrieve-used-names objects) - svg-name (str/replace (:name svg-data) ".svg" "") + svg-name (str/replace (:name svg-data) ".svg" "") - svg-data (-> svg-data - (assoc :x x - :y y - :offset-x vb-x - :offset-y vb-y - :width vb-width - :height vb-height - :name svg-name)) + svg-data (-> svg-data + (assoc :x x + :y y + :offset-x vb-x + :offset-y vb-y + :width vb-width + :height vb-height + :name svg-name)) - [def-nodes svg-data] (-> svg-data - (usvg/fix-default-values) - (usvg/fix-percents) - (usvg/extract-defs)) + [def-nodes svg-data] (-> svg-data + (usvg/fix-default-values) + (usvg/fix-percents) + (usvg/extract-defs)) - svg-data (assoc svg-data :defs def-nodes) + svg-data (assoc svg-data :defs def-nodes) - root-shape (create-svg-root frame-id parent-id svg-data) - root-id (:id root-shape) + root-shape (create-svg-root frame-id parent-id svg-data) + root-id (:id root-shape) - ;; In penpot groups have the size of their children. To respect the imported svg size and empty space let's create a transparent shape as background to respect the imported size - base-background-shape {:tag :rect - :attrs {:x (str vb-x) - :y (str vb-y) - :width (str vb-width) - :height (str vb-height) - :fill "none" - :id "base-background"} - :hidden true - :content []} + ;; In penpot groups have the size of their children. To respect the imported svg size and empty space let's create a transparent shape as background to respect the imported size + base-background-shape {:tag :rect + :attrs {:x (str vb-x) + :y (str vb-y) + :width (str vb-width) + :height (str vb-height) + :fill "none" + :id "base-background"} + :hidden true + :content []} - svg-data (-> svg-data - (assoc :defs def-nodes) - (assoc :content (into [base-background-shape] (:content svg-data)))) + svg-data (-> svg-data + (assoc :defs def-nodes) + (assoc :content (into [base-background-shape] (:content svg-data)))) - ;; Create the root shape - new-shape (dwsh/make-new-shape root-shape objects selected) + ;; Create the root shape + new-shape (dwsh/make-new-shape root-shape objects selected) - root-attrs (-> (:attrs svg-data) - (usvg/format-styles)) + root-attrs (-> (:attrs svg-data) + (usvg/format-styles)) - [_ new-children] - (reduce (partial create-svg-children objects selected frame-id root-id svg-data) - [unames []] - (d/enumerate (->> (:content svg-data) - (mapv #(usvg/inherit-attributes root-attrs %)))))] + [_ new-children] + (reduce (partial create-svg-children objects selected frame-id root-id svg-data) + [unames []] + (d/enumerate (->> (:content svg-data) + (mapv #(usvg/inherit-attributes root-attrs %)))))] - [new-shape new-children]) - - (catch :default e - (.error js/console "Error SVG" e) - (rx/throw {:type :svg-parser - :data e})))) + [new-shape new-children])) (defn add-svg-shapes [svg-data position] (ptk/reify ::add-svg-shapes ptk/WatchEvent (watch [it state _] - (let [page-id (:current-page-id state) - objects (wsh/lookup-page-objects state page-id) - frame-id (ctst/top-nested-frame objects position) - selected (wsh/lookup-selected state) - page-objects (wsh/lookup-page-objects state) - base (cph/get-base-shape page-objects selected) - selected-frame? (and (= 1 (count selected)) - (= :frame (get-in objects [(first selected) :type]))) + (try + (let [page-id (:current-page-id state) + objects (wsh/lookup-page-objects state page-id) + frame-id (ctst/top-nested-frame objects position) + selected (wsh/lookup-selected state) + page-objects (wsh/lookup-page-objects state) + base (cph/get-base-shape page-objects selected) + selected-frame? (and (= 1 (count selected)) + (= :frame (get-in objects [(first selected) :type]))) - parent-id (if - (or selected-frame? (empty? selected)) frame-id - (:parent-id base)) + parent-id + (if (or selected-frame? (empty? selected)) + frame-id + (:parent-id base)) - [new-shape new-children] - (create-svg-shapes svg-data position objects frame-id parent-id selected true) - changes (-> (pcb/empty-changes it page-id) - (pcb/with-objects objects) - (pcb/add-object new-shape)) + [new-shape new-children] + (create-svg-shapes svg-data position objects frame-id parent-id selected true) + changes (-> (pcb/empty-changes it page-id) + (pcb/with-objects objects) + (pcb/add-object new-shape)) - changes - (reduce (fn [changes [index new-child]] - (-> changes - (pcb/add-object new-child) - (pcb/change-parent (:parent-id new-child) [new-child] index))) - changes - (d/enumerate new-children)) + changes + (reduce (fn [changes [index new-child]] + (-> changes + (pcb/add-object new-child) + (pcb/change-parent (:parent-id new-child) [new-child] index))) + changes + (d/enumerate new-children)) - changes (pcb/resize-parents changes - (->> changes - :redo-changes - (filter #(= :add-obj (:type %))) - (map :id) - reverse - vec)) - undo-id (js/Symbol)] + changes (pcb/resize-parents changes + (->> changes + :redo-changes + (filter #(= :add-obj (:type %))) + (map :id) + reverse + vec)) + undo-id (js/Symbol)] - (rx/of (dwu/start-undo-transaction undo-id) - (dch/commit-changes changes) - (dws/select-shapes (d/ordered-set (:id new-shape))) - (ptk/data-event :layout/update [(:id new-shape)]) - (dwu/commit-undo-transaction undo-id)))))) + (rx/of (dwu/start-undo-transaction undo-id) + (dch/commit-changes changes) + (dws/select-shapes (d/ordered-set (:id new-shape))) + (ptk/data-event :layout/update [(:id new-shape)]) + (dwu/commit-undo-transaction undo-id))) + + (catch :default e + (.error js/console "Error SVG" e) + (rx/throw {:type :svg-parser + :data e})))))) diff --git a/frontend/src/app/main/store.cljs b/frontend/src/app/main/store.cljs index cb2d99824..87fa4a050 100644 --- a/frontend/src/app/main/store.cljs +++ b/frontend/src/app/main/store.cljs @@ -46,7 +46,9 @@ (defonce state (ptk/store {:resolve ptk/resolve :on-event on-event - :on-error (fn [e] (@on-error e))})) + :on-error (fn [e] + (.log js/console "ERROR!!" e) + (@on-error e))})) (defonce stream (ptk/input-stream state)) diff --git a/frontend/src/app/util/svg.cljs b/frontend/src/app/util/svg.cljs index 03d541fa5..21f084d84 100644 --- a/frontend/src/app/util/svg.cljs +++ b/frontend/src/app/util/svg.cljs @@ -820,6 +820,10 @@ (defn line->path [{:keys [attrs] :as node}] (let [tag :path {:keys [x1 y1 x2 y2]} attrs + x1 (or x1 0) + y1 (or y1 0) + x2 (or x2 0) + y2 (or y2 0) attrs (-> attrs (dissoc :x1 :x2 :y1 :y2) (assoc :d (str "M" x1 "," y1 " L" x2 "," y2)))]