From 5ad31a878b7d0ada1aa57dc097948415f119cfe6 Mon Sep 17 00:00:00 2001 From: Aitor Date: Wed, 3 Jan 2024 10:02:13 +0100 Subject: [PATCH] :bug: Fix rasterizer not loading embedded styles --- frontend/src/app/rasterizer.cljs | 54 +++++++++++++++++++++++++------- frontend/src/app/util/dom.cljs | 4 +++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/frontend/src/app/rasterizer.cljs b/frontend/src/app/rasterizer.cljs index d6eeb474c..157b57a65 100644 --- a/frontend/src/app/rasterizer.cljs +++ b/frontend/src/app/rasterizer.cljs @@ -96,10 +96,16 @@ :method :get :mode :cors :omit-default-headers true}) - (rx/map :body) - (rx/mapcat wapi/read-file-as-data-url) - (rx/tap (fn [data-uri] - (.set data-uri-cache uri (wapi/create-blob data-uri "text/plain"))))))) + (rx/catch (fn [cause] + (log/error :hint "fetching data uri" + :cause cause) + (rx/of nil))) + (rx/mapcat (fn [response] + (if (nil? response) + (rx/of uri) + (->> (rx/of (:body response)) + (rx/mapcat wapi/read-file-as-data-url) + (rx/tap (fn [data-uri] (.set data-uri-cache uri (wapi/create-blob data-uri "text/plain"))))))))))) (defn- svg-update-image! "Updates an image in an SVG to a Data URI." @@ -128,27 +134,53 @@ (dom/append-child! style (dom/create-text svg styles)) (dom/append-child! doc style))) -(defn- svg-resolve-styles! - "Resolves all fonts in an SVG to Data URIs." - [svg styles] +(defn- svg-resolve-external-resources + "Resolves all external resources in an SVG to Data URIs." + [styles] (->> (rx/from (re-seq #"url\((https?://[^)]+)\)" styles)) (rx/map second) (rx/mapcat (fn [url] - (->> (fetch-as-data-uri url) - (rx/map (fn [uri] [url uri]))))) - + (->> (fetch-as-data-uri url) + (rx/map (fn [uri] [url uri]))))) (rx/reduce (fn [styles [url uri]] (str/replace styles url uri)) - styles) + styles))) + +(defn- svg-resolve-styles! + "Resolves all fonts in an SVG to Data URIs." + [svg styles] + (->> (svg-resolve-external-resources styles) (rx/tap (partial svg-add-style! svg)) (rx/ignore))) +(defn- svg-resolve-inline-styles! + "Resolves all inline styles in an SVG to Data URIs." + [svg] + (->> (rx/from (dom/query-all svg "[style]")) + (rx/mapcat (fn [node] + (let [styles (dom/get-attribute node "style")] + (->> (svg-resolve-external-resources styles) + (rx/tap (fn [styles] (dom/set-attribute! node "style" styles))))))) + (rx/ignore))) + +(defn- svg-resolve-style-elements! + "Resolves all style elements in an SVG to Data URIs." + [svg] + (->> (rx/from (dom/query-all svg "style")) + (rx/mapcat (fn [node] + (let [styles (dom/get-text node)] + (->> (svg-resolve-external-resources styles) + (rx/tap (fn [styles] (dom/set-text! node styles))))))) + (rx/ignore))) + (defn- svg-resolve-all! "Resolves all images and fonts in an SVG to Data URIs." [svg styles] (rx/concat (svg-resolve-images! svg) (svg-resolve-styles! svg styles) + (svg-resolve-inline-styles! svg) + (svg-resolve-style-elements! svg) (rx/of svg))) (defn- svg-parse diff --git a/frontend/src/app/util/dom.cljs b/frontend/src/app/util/dom.cljs index 8b0478478..998a581eb 100644 --- a/frontend/src/app/util/dom.cljs +++ b/frontend/src/app/util/dom.cljs @@ -504,6 +504,10 @@ (.setAttribute node property value)) node) +(defn get-text [^js node] + (when (some? node) + (.-textContent node))) + (defn set-text! [^js node text] (when (some? node) (set! (.-textContent node) text))