From d684970bfbb6dfa0641c029cda9b15168351c960 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 May 2022 10:36:30 +0200 Subject: [PATCH 1/4] :bug: Fix problem with single line texts --- .../src/app/main/ui/workspace/shapes/text/viewport_texts.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts.cljs b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts.cljs index c5e38e957b..2e65fd79ce 100644 --- a/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/text/viewport_texts.cljs @@ -33,7 +33,7 @@ (let [modifier (get modifiers id) modifier (d/update-when modifier :modifiers dissoc :displacement :rotation) shape (cond-> shape - (not (gsh/empty-modifiers? modifier)) + (not (gsh/empty-modifiers? (:modifiers modifier))) (-> (assoc :grow-type :fixed) (merge modifier) gsh/transform-shape))] (strip-position-data shape))) From 5a07599fc781cb080944bdf51798f64452e3585c Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 May 2022 12:26:47 +0200 Subject: [PATCH 2/4] :bug: Fix problem with thumbnail re-rendering --- .../app/main/ui/workspace/shapes/frame.cljs | 15 +++++++++---- .../shapes/frame/thumbnail_render.cljs | 21 +++++++++---------- frontend/src/app/util/dom.cljs | 5 +++-- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index a2b71dee77..782600633c 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -10,6 +10,7 @@ [app.common.data.macros :as dm] [app.common.uuid :as uuid] [app.main.data.workspace.thumbnails :as dwt] + [app.main.fonts :as fonts] [app.main.refs :as refs] [app.main.ui.context :as ctx] [app.main.ui.hooks :as hooks] @@ -27,19 +28,17 @@ [shape-wrapper] (let [frame-shape (frame/frame-shape shape-wrapper)] (mf/fnc frame-shape-inner - {::mf/wrap [#(mf/memo' % (mf/check-props ["shape" "fonts"]))] + {::mf/wrap [#(mf/memo' % (mf/check-props ["shape"]))] ::mf/wrap-props false ::mf/forward-ref true} [props ref] (let [shape (unchecked-get props "shape") - fonts (unchecked-get props "fonts") childs-ref (mf/use-memo (mf/deps (:id shape)) #(refs/children-objects (:id shape))) childs (mf/deref childs-ref)] [:& (mf/provider embed/context) {:value true} [:& shape-container {:shape shape :ref ref} - [:& ff/fontfaces-style {:fonts fonts}] [:& frame-shape {:shape shape :childs childs} ]]])))) (defn check-props @@ -90,13 +89,20 @@ disable-thumbnail? (d/not-empty? (dm/get-in modifiers [(:id shape) :modifiers])) [on-load-frame-dom thumb-renderer] - (ftr/use-render-thumbnail page-id shape node-ref rendered? thumbnail? disable-thumbnail?) + (ftr/use-render-thumbnail page-id shape node-ref rendered? thumbnail-data-ref disable-thumbnail?) on-frame-load (fns/use-node-store thumbnail? node-ref rendered?)] (fdm/use-dynamic-modifiers objects @node-ref modifiers) + (mf/use-effect + (mf/deps fonts) + (fn [] + (->> (rx/from fonts) + (rx/merge-map fonts/fetch-font-css) + (rx/ignore)))) + (mf/use-effect (fn [] ;; When a change in the data is received a "force-render" event is emited @@ -121,6 +127,7 @@ [:& (mf/provider ctx/render-ctx) {:value render-id} [:g.frame-container {:key "frame-container" :ref on-frame-load} + [:& ff/fontfaces-style {:fonts fonts}] [:g.frame-thumbnail-wrapper {:id (dm/str "thumbnail-container-" (:id shape))} [:> frame/frame-thumbnail {:key (dm/str (:id shape)) :shape (cond-> shape diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs index 2aaceb8c8a..002926e8d5 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs @@ -43,7 +43,7 @@ (defn use-render-thumbnail "Hook that will create the thumbnail thata" - [page-id {:keys [id x y width height] :as shape} node-ref rendered? thumbnail? disable?] + [page-id {:keys [id x y width height] :as shape} node-ref rendered? thumbnail-data-ref disable?] (let [frame-canvas-ref (mf/use-ref nil) frame-image-ref (mf/use-ref nil) @@ -58,8 +58,6 @@ shape-ref (hooks/use-update-var shape) - thumbnail-ref? (mf/use-var thumbnail?) - updates-str (mf/use-memo #(rx/subject)) on-image-load @@ -77,8 +75,12 @@ (fn [] (when (and (some? @node-ref) (not @disable-ref?)) (let [node @node-ref + frame-html (dom/node->xml node) {:keys [x y width height]} @shape-ref + + style-str (or (-> node dom/get-parent (dom/query "style") dom/node->xml) "") + svg-node (-> (dom/make-node "http://www.w3.org/2000/svg" "svg") (dom/set-property! "version" "1.1") @@ -86,7 +88,7 @@ (dom/set-property! "width" width) (dom/set-property! "height" height) (dom/set-property! "fill" "none") - (obj/set! "innerHTML" frame-html)) + (obj/set! "innerHTML" (dm/str style-str frame-html))) img-src (-> svg-node dom/node->xml dom/svg->data-uri)] (reset! image-url img-src)))) @@ -94,7 +96,9 @@ (mf/use-callback (fn [node] (when (and (some? node) (nil? @observer-ref)) - (rx/push! updates-str :update) + (when-not (some? @thumbnail-data-ref) + (rx/push! updates-str :update)) + (let [observer (js/MutationObserver. (partial rx/push! updates-str))] (.observe observer node #js {:childList true :attributes true :characterData true :subtree true}) (reset! observer-ref observer)))))] @@ -102,7 +106,7 @@ (mf/use-effect (fn [] (let [subid (->> updates-str - (rx/debounce 200) + (rx/debounce 400) (rx/subs on-update-frame))] #(rx/dispose! subid)))) @@ -111,11 +115,6 @@ (fn [] (reset! disable-ref? disable?))) - (mf/use-effect - (mf/deps thumbnail?) - (fn [] - (reset! thumbnail-ref? thumbnail?))) - (mf/use-effect (fn [] #(when (and (some? @node-ref) @rendered?) diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index e6fe6cbecc..dc25d62b39 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -335,8 +335,9 @@ (defn node->xml [node] - (-> (js/XMLSerializer.) - (.serializeToString node))) + (when (some? node) + (-> (js/XMLSerializer.) + (.serializeToString node)))) (defn svg->data-uri [svg] From edce45095e5e4dd18845986a772a9df919de9314 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 May 2022 13:58:12 +0200 Subject: [PATCH 3/4] :bug: Remove xlinkHref to resolve Safari problem --- frontend/src/app/main/data/workspace/svg_upload.cljs | 4 ++-- frontend/src/app/main/ui/icons.clj | 2 +- frontend/src/app/main/ui/shapes/custom_stroke.cljs | 12 ++++++------ frontend/src/app/main/ui/shapes/fills.cljs | 2 +- frontend/src/app/main/ui/shapes/frame.cljs | 2 +- .../ui/workspace/shapes/frame/thumbnail_render.cljs | 2 +- .../src/app/main/ui/workspace/viewport/widgets.cljs | 2 +- frontend/src/app/render.cljs | 2 +- frontend/src/app/util/svg.cljs | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index df39c8bc2d..40d9d14eeb 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -326,7 +326,7 @@ transform (->> svg-transform (gmt/transform-in (gpt/point svg-data))) - image-url (:xlink:href attrs) + image-url (or (:href attrs) (:xlink:href attrs)) image-data (get-in svg-data [:image-data image-url]) rect (->> (select-keys attrs [:x :y :width :height]) @@ -352,7 +352,7 @@ (merge rect-metadata) (assoc :svg-viewbox (select-keys rect [:x :y :width :height])) - (assoc :svg-attrs (dissoc attrs :x :y :width :height :xlink:href)))))) + (assoc :svg-attrs (dissoc attrs :x :y :width :height :href :xlink:href)))))) (defn parse-svg-element [frame-id svg-data element-data unames] (let [{:keys [tag attrs]} element-data diff --git a/frontend/src/app/main/ui/icons.clj b/frontend/src/app/main/ui/icons.clj index a31a1fa92d..e78929591a 100644 --- a/frontend/src/app/main/ui/icons.clj +++ b/frontend/src/app/main/ui/icons.clj @@ -13,5 +13,5 @@ class (str "icon-" (name id))] `(rumext.alpha/html [:svg {:width 500 :height 500 :class ~class} - [:use {:xlinkHref ~href}]]))) + [:use {:href ~href}]]))) diff --git a/frontend/src/app/main/ui/shapes/custom_stroke.cljs b/frontend/src/app/main/ui/shapes/custom_stroke.cljs index b125f8d45f..ba4776f2b8 100644 --- a/frontend/src/app/main/ui/shapes/custom_stroke.cljs +++ b/frontend/src/app/main/ui/shapes/custom_stroke.cljs @@ -34,7 +34,7 @@ clip-id (str "inner-stroke-" render-id "-" (:id shape) suffix) shape-id (str "stroke-shape-" render-id "-" (:id shape) suffix)] [:> "clipPath" #js {:id clip-id} - [:use {:xlinkHref (str "#" shape-id)}]])) + [:use {:href (str "#" shape-id)}]])) (mf/defc outer-stroke-mask [{:keys [shape render-id index]}] @@ -58,10 +58,10 @@ :width (:width bounding-box) :height (:height bounding-box) :maskUnits "userSpaceOnUse"} - [:use {:xlinkHref (str "#" shape-id) + [:use {:href (str "#" shape-id) :style #js {:fill "none" :stroke "white" :strokeWidth (* stroke-width 2)}}] - [:use {:xlinkHref (str "#" shape-id) + [:use {:href (str "#" shape-id) :style #js {:fill "black" :stroke "none"}}]])) @@ -233,7 +233,7 @@ (obj/clone) (obj/without ["fill" "fillOpacity" "stroke" "strokeWidth" "strokeOpacity" "strokeStyle" "strokeDasharray"]))))]] - [:use {:xlinkHref (str "#" shape-id) + [:use {:href (str "#" shape-id) :mask (str "url(#" stroke-mask-id ")") :style (-> (obj/get base-props "style") (obj/clone) @@ -241,7 +241,7 @@ (obj/without ["fill" "fillOpacity"]) (obj/set! "fill" "none"))}] - [:use {:xlinkHref (str "#" shape-id) + [:use {:href (str "#" shape-id) :style (-> (obj/get base-props "style") (obj/clone) (obj/set! "stroke" "none"))}]])) @@ -277,7 +277,7 @@ [:& stroke-defs {:shape shape :render-id render-id :index index}] [:> elem-name shape-props]] - [:use {:xlinkHref (str "#" shape-id) + [:use {:href (str "#" shape-id) :clipPath clip-path}]])) ; The SVG standard does not implement yet the 'stroke-alignment' diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index 45ba0586e4..a3a8769e74 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -79,7 +79,7 @@ (obj/set! "height" height))]) (when has-image? - [:image {:xlinkHref (get embed uri uri) + [:image {:href (get embed uri uri) :preserveAspectRatio "none" :width width :height height}])]])]))))) diff --git a/frontend/src/app/main/ui/shapes/frame.cljs b/frontend/src/app/main/ui/shapes/frame.cljs index 168e268939..8e4d078662 100644 --- a/frontend/src/app/main/ui/shapes/frame.cljs +++ b/frontend/src/app/main/ui/shapes/frame.cljs @@ -68,7 +68,7 @@ [:image.frame-thumbnail {:id (dm/str "thumbnail-" (:id shape)) - :xlinkHref (:thumbnail shape) + :href (:thumbnail shape) :x (:x shape) :y (:y shape) :width (:width shape) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs index 002926e8d5..0630fe201a 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs @@ -137,7 +137,7 @@ [:image {:ref frame-image-ref :x (:x shape) :y (:y shape) - :xlinkHref @image-url + :href @image-url :width (:width shape) :height (:height shape) :on-load on-image-load}]]))])) diff --git a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs index 1c22c42d18..75cbaa64d0 100644 --- a/frontend/src/app/main/ui/workspace/viewport/widgets.cljs +++ b/frontend/src/app/main/ui/workspace/viewport/widgets.cljs @@ -147,7 +147,7 @@ :class "workspace-frame-icon" :style {:fill (when selected? "var(--color-primary-dark)")} :visibility (if show-artboard-names? "visible" "hidden")} - [:use {:xlinkHref "#icon-set-thumbnail"}]]]) + [:use {:href "#icon-set-thumbnail"}]]]) [:text {:x text-pos-x :y 0 :width width diff --git a/frontend/src/app/render.cljs b/frontend/src/app/render.cljs index 74280552c8..5d921f0a72 100644 --- a/frontend/src/app/render.cljs +++ b/frontend/src/app/render.cljs @@ -264,7 +264,7 @@ :embed embed} (when-let [component-id (:component-id @state)] - [:use {:x 0 :y 0 :xlinkHref (str "#" component-id)}])]] + [:use {:x 0 :y 0 :href (str "#" component-id)}])]] ]))) diff --git a/frontend/src/app/util/svg.cljs b/frontend/src/app/util/svg.cljs index 198fd91c20..0fef4753e2 100644 --- a/frontend/src/app/util/svg.cljs +++ b/frontend/src/app/util/svg.cljs @@ -961,5 +961,5 @@ (let [redfn (fn [acc {:keys [tag attrs]}] (cond-> acc (= :image tag) - (conj (:xlink:href attrs))))] + (conj (or (:href attrs) (:xlink:href attrs)))))] (reduce-nodes redfn [] svg-data ))) From 01664a04fc924645984b35b39f94c201a32fa22e Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Tue, 17 May 2022 14:08:40 +0200 Subject: [PATCH 4/4] :bug: Problem recalculating thumbnails --- frontend/src/app/main/ui/shapes/fills.cljs | 6 +----- .../app/main/ui/workspace/shapes/frame.cljs | 4 +++- .../shapes/frame/thumbnail_render.cljs | 20 ++++++++++++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/frontend/src/app/main/ui/shapes/fills.cljs b/frontend/src/app/main/ui/shapes/fills.cljs index a3a8769e74..2aee6e1226 100644 --- a/frontend/src/app/main/ui/shapes/fills.cljs +++ b/frontend/src/app/main/ui/shapes/fills.cljs @@ -43,15 +43,11 @@ embed (embed/use-data-uris [uri]) transform (gsh/transform-matrix shape) - ;; When true the image has not loaded yet - loading? (and (some? uri) (not (contains? embed uri))) - pattern-attrs (cond-> #js {:patternUnits "userSpaceOnUse" :x x :y y :height height - :width width - :data-loading loading?} + :width width} (= :path (:type shape)) (obj/set! "patternTransform" transform))] diff --git a/frontend/src/app/main/ui/workspace/shapes/frame.cljs b/frontend/src/app/main/ui/workspace/shapes/frame.cljs index 782600633c..522c172588 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame.cljs @@ -126,7 +126,9 @@ (when (not @rendered?) (reset! rendered? true))))) [:& (mf/provider ctx/render-ctx) {:value render-id} - [:g.frame-container {:key "frame-container" :ref on-frame-load} + [:g.frame-container {:id (dm/str "frame-container-" (:id shape)) + :key "frame-container" + :ref on-frame-load} [:& ff/fontfaces-style {:fonts fonts}] [:g.frame-thumbnail-wrapper {:id (dm/str "thumbnail-container-" (:id shape))} [:> frame/frame-thumbnail {:key (dm/str (:id shape)) diff --git a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs index 0630fe201a..3280108a15 100644 --- a/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs +++ b/frontend/src/app/main/ui/workspace/shapes/frame/thumbnail_render.cljs @@ -6,6 +6,7 @@ (ns app.main.ui.workspace.shapes.frame.thumbnail-render (:require + [app.common.data :as d] [app.common.data.macros :as dm] [app.common.math :as mth] [app.main.data.workspace :as dw] @@ -15,6 +16,7 @@ [app.util.object :as obj] [app.util.timers :as ts] [beicon.core :as rx] + [cuerdas.core :as str] [rumext.alpha :as mf])) ;; (def thumbnail-scale-factor 2) @@ -41,6 +43,16 @@ (.error js/console err) nil))) +(defn- remove-embed-images-changes + "Remove the changes related to change a url for its embed value. This is necessary + so we don't have to recalculate the thumbnail when the image loads." + [changes] + (->> changes + (remove (fn [change] + (and (= "attributes" (.-type change)) + (= "href" (.-attributeName change)) + (str/starts-with? (.-oldValue change) "http")))))) + (defn use-render-thumbnail "Hook that will create the thumbnail thata" [page-id {:keys [id x y width height] :as shape} node-ref rendered? thumbnail-data-ref disable?] @@ -75,11 +87,11 @@ (fn [] (when (and (some? @node-ref) (not @disable-ref?)) (let [node @node-ref - frame-html (dom/node->xml node) {:keys [x y width height]} @shape-ref - style-str (or (-> node dom/get-parent (dom/query "style") dom/node->xml) "") + style-node (dom/query (dm/str "#frame-container-" (:id shape) " style")) + style-str (or (-> style-node dom/node->xml) "") svg-node (-> (dom/make-node "http://www.w3.org/2000/svg" "svg") @@ -100,12 +112,14 @@ (rx/push! updates-str :update)) (let [observer (js/MutationObserver. (partial rx/push! updates-str))] - (.observe observer node #js {:childList true :attributes true :characterData true :subtree true}) + (.observe observer node #js {:childList true :attributes true :attributeOldValue true :characterData true :subtree true}) (reset! observer-ref observer)))))] (mf/use-effect (fn [] (let [subid (->> updates-str + (rx/map remove-embed-images-changes) + (rx/filter d/not-empty?) (rx/debounce 400) (rx/subs on-update-frame))] #(rx/dispose! subid))))