Browse Source

fix(db): css assets loading

- move make-asset-url to assets-handler
- handle assets for db-based graph in add-style-if-exists!
Andelf 1 year ago
parent
commit
329818e4c4

+ 1 - 1
deps/graph-parser/src/logseq/graph_parser/exporter.cljs

@@ -564,7 +564,7 @@
 
 (defn add-file-to-db-graph
   "Parse file and save parsed data to the given db graph. Options available:
-  
+
 * :extract-options - Options map to pass to extract/extract
 * :user-options - User provided options maps that alter how a file is converted to db graph. Current options
    are :tag-classes (set) and :property-classes (set).

+ 1 - 1
src/main/frontend/components/block.cljs

@@ -385,7 +385,7 @@
                    (mobile-util/native-platform?)
                    (config/db-based-graph? (state/get-current-repo)))
                (nil? @src))
-      (p/then (editor-handler/make-asset-url href) #(reset! src %)))
+      (p/then (assets-handler/make-asset-url href) #(reset! src %)))
 
     (when @src
       ;; NOTE(andelf): Under nfs context, src might be a bare blob:http://..../uuid URI without ext info

+ 5 - 4
src/main/frontend/config.cljs

@@ -500,11 +500,12 @@
           ;; BUG: use "assets" as fake current directory
           assets-link-fn (fn [_]
                            (let [graph-root (get-repo-dir (state/get-current-repo))
-                                 protocol (if (string/starts-with? graph-root "file:") "" protocol)
-                                 full-path (path/path-join protocol graph-root "assets")]
+                                 full-path (if (util/safe-re-find #"^(file|assets):" graph-root)
+                                             (path/path-join graph-root "assets")
+                                             (path/path-join protocol graph-root "assets"))]
                              (str (cond-> full-path
-                                          (mobile-util/native-platform?)
-                                          (mobile-util/convert-file-src))
+                                    (mobile-util/native-platform?)
+                                    (mobile-util/convert-file-src))
                                   "/")))]
       (string/replace source #"\.\./assets/" assets-link-fn))))
 

+ 1 - 1
src/main/frontend/extensions/pdf/assets.cljs

@@ -288,7 +288,7 @@
   [block]
   (when-let [asset-path' (and block (pdf-utils/get-area-block-asset-url
                                      block (db-utils/pull (:db/id (:block/page block)))))]
-    (let [asset-path (editor-handler/make-asset-url asset-path')]
+    (let [asset-path (assets-handler/make-asset-url asset-path')]
       [:span.hl-area
        [:span.actions
         (when-not config/publishing?

+ 10 - 10
src/main/frontend/extensions/pdf/toolbar.cljs

@@ -1,20 +1,20 @@
 (ns frontend.extensions.pdf.toolbar
   (:require [cljs-bean.core :as bean]
             [clojure.string :as string]
+            [frontend.components.svg :as svg]
             [frontend.context.i18n :refer [t]]
-            [rum.core :as rum]
-            [promesa.core :as p]
+            [frontend.extensions.pdf.assets :as pdf-assets]
+            [frontend.extensions.pdf.utils :as pdf-utils]
+            [frontend.extensions.pdf.windows :refer [resolve-own-container] :as pdf-windows]
+            [frontend.handler.assets :as assets-handler]
+            [frontend.handler.notification :as notification]
             [frontend.rum :refer [use-atom]]
             [frontend.state :as state]
-            [frontend.util :as util]
             [frontend.storage :as storage]
             [frontend.ui :as ui]
-            [frontend.components.svg :as svg]
-            [frontend.extensions.pdf.assets :as pdf-assets]
-            [frontend.handler.editor :as editor-handler]
-            [frontend.extensions.pdf.utils :as pdf-utils]
-            [frontend.handler.notification :as notification]
-            [frontend.extensions.pdf.windows :refer [resolve-own-container] :as pdf-windows]))
+            [frontend.util :as util]
+            [promesa.core :as p]
+            [rum.core :as rum]))
 
 (declare make-docinfo-in-modal)
 
@@ -400,7 +400,7 @@
           (if-let [img-stamp (:image content)]
             (let [fpath (pdf-assets/resolve-area-image-file
                          img-stamp (state/get-current-pdf) hl)
-                  fpath (editor-handler/make-asset-url fpath)]
+                  fpath (assets-handler/make-asset-url fpath)]
               [:p.area-wrap
                [:img {:src fpath}]])
             [:p.text-wrap (:text content)])])))))

+ 2 - 1
src/main/frontend/extensions/tldraw.cljs

@@ -10,6 +10,7 @@
             [frontend.db :as db]
             [frontend.extensions.pdf.assets :as pdf-assets]
             [frontend.handler.editor :as editor-handler]
+            [frontend.handler.assets :as assets-handler]
             [frontend.handler.route :as route-handler]
             [frontend.handler.whiteboard :as whiteboard-handler]
             [frontend.handler.history :as history]
@@ -117,7 +118,7 @@
    :isWhiteboardPage model/whiteboard-page?
    :isMobile util/mobile?
    :saveAsset save-asset-handler
-   :makeAssetUrl editor-handler/make-asset-url
+   :makeAssetUrl assets-handler/make-asset-url
    :inflateAsset (fn [src] (clj->js (pdf-assets/inflate-asset src)))
    :setCurrentPdf (fn [src] (state/set-current-pdf! (if src (pdf-assets/inflate-asset src) nil)))
    :copyToClipboard (fn [text, html] (util/copy-to-clipboard! text :html html))

+ 75 - 10
src/main/frontend/handler/assets.cljs

@@ -1,13 +1,16 @@
 (ns ^:no-doc frontend.handler.assets
-  (:require [frontend.state :as state]
-            [medley.core :as medley]
-            [frontend.util :as util]
+  (:require [clojure.string :as string]
             [frontend.config :as config]
+            [frontend.fs :as fs]
+            [frontend.fs.nfs :as nfs]
             [frontend.mobile.util :as mobile-util]
+            [frontend.state :as state]
+            [frontend.util :as util]
             [logseq.common.config :as common-config]
-            [clojure.string :as string]
             [logseq.common.path :as path]
-            [logseq.common.util :as common-util]))
+            [logseq.common.util :as common-util]
+            [medley.core :as medley]
+            [promesa.core :as p]))
 
 (defn alias-enabled?
   []
@@ -127,8 +130,70 @@
              (util/format "[[%s][%s]]" url file-name))
       nil)))
 
-(comment
- (normalize-asset-resource-url "https://x.com/a.pdf")
- (normalize-asset-resource-url "./a/b.pdf")
- (normalize-asset-resource-url "assets/a/b.pdf")
- (normalize-asset-resource-url "@图书/a/b.pdf"))
+(defn <make-data-url
+  [path]
+  (let [repo-dir (config/get-repo-dir (state/get-current-repo))]
+    (p/let [binary (fs/read-file repo-dir path {})
+            blob (js/Blob. (array binary) (clj->js {:type "image"}))]
+      (when blob (js/URL.createObjectURL blob)))))
+
+(defn <expand-assets-links-for-db-graph
+  "Expand ../assets/ links in custom.css file to blob url.
+
+   Only for db-based graph"
+  [css]
+  (let [rel-paths (re-seq #"\(['\"]?(\.\./assets/.*?)['\"]?\)" css)
+        rel-paths (vec (set (map second rel-paths)))
+        fixed-rel-paths (map (fn [p] (path/path-join "./logseq/" p)) rel-paths)]
+    (p/let [blob-urls (p/all (map <make-data-url fixed-rel-paths))]
+      (reduce (fn [css [rel-path blob-url]]
+                (string/replace css rel-path (str "'" blob-url "'")))
+              css
+              (map vector rel-paths blob-urls)))))
+
+(defonce *assets-url-cache (atom {}))
+
+(defn make-asset-url
+  "Make asset URL for UI element, to fill img.src"
+  [path] ;; path start with "/assets"(editor) or compatible for "../assets"(whiteboards)
+  (if config/publishing?
+    ;; Relative path needed since assets are not under '/' if published graph is not under '/'
+    (string/replace-first path #"^/" "")
+    (let [repo      (state/get-current-repo)
+          repo-dir  (config/get-repo-dir repo)
+          ;; Hack for path calculation
+          path      (string/replace path #"^(\.\.)?/" "./")
+          full-path (path/path-join repo-dir path)
+          data-url? (string/starts-with? path "data:")]
+      (cond
+        data-url?
+        path ;; just return the original
+
+        (and (alias-enabled?)
+             (check-alias-path? path))
+        (resolve-asset-real-path-url (state/get-current-repo) path)
+
+        (util/electron?)
+        (path/prepend-protocol "assets:" full-path)
+
+        (mobile-util/native-platform?)
+        (mobile-util/convert-file-src full-path)
+
+        (config/db-based-graph? (state/get-current-repo)) ; memory fs
+        (p/let [binary (fs/read-file repo-dir path {})
+                blob (js/Blob. (array binary) (clj->js {:type "image"}))]
+          (when blob (js/URL.createObjectURL blob)))
+
+        :else ;; nfs
+        (let [handle-path (str "handle/" full-path)
+              cached-url  (get @*assets-url-cache (keyword handle-path))]
+          (if cached-url
+            (p/resolved cached-url)
+            ;; Loading File from handle cache
+            ;; Use await file handle, to ensure all handles are loaded.
+            (p/let [handle (nfs/await-get-nfs-file-handle repo handle-path)
+                    file   (and handle (.getFile handle))]
+              (when file
+                (p/let [url (js/URL.createObjectURL file)]
+                  (swap! *assets-url-cache assoc (keyword handle-path) url)
+                  url)))))))))

+ 0 - 48
src/main/frontend/handler/editor.cljs

@@ -15,7 +15,6 @@
             [frontend.format.block :as block]
             [frontend.format.mldoc :as mldoc]
             [frontend.fs :as fs]
-            [frontend.fs.nfs :as nfs]
             [logseq.common.path :as path]
             [frontend.extensions.pdf.utils :as pdf-utils]
             [frontend.handler.assets :as assets-handler]
@@ -1482,53 +1481,6 @@
                    (fs/write-file! repo dir file-rpath (.stream file) nil))
                  [file-rpath file (path/path-join dir file-rpath) matched-alias])))))))
 
-(defonce *assets-url-cache (atom {}))
-
-(defn make-asset-url
-  "Make asset URL for UI element, to fill img.src"
-  [path] ;; path start with "/assets"(editor) or compatible for "../assets"(whiteboards)
-  (if config/publishing?
-    ;; Relative path needed since assets are not under '/' if published graph is not under '/'
-    (string/replace-first path #"^/" "")
-    (let [repo      (state/get-current-repo)
-          repo-dir  (config/get-repo-dir repo)
-          ;; Hack for path calculation
-          path      (string/replace path #"^(\.\.)?/" "./")
-          full-path (path/path-join repo-dir path)
-          data-url? (string/starts-with? path "data:")]
-      (cond
-        data-url?
-        path ;; just return the original
-
-        (and (assets-handler/alias-enabled?)
-             (assets-handler/check-alias-path? path))
-        (assets-handler/resolve-asset-real-path-url (state/get-current-repo) path)
-
-        (util/electron?)
-        (path/prepend-protocol "assets:" full-path)
-
-        (mobile-util/native-platform?)
-        (mobile-util/convert-file-src full-path)
-
-        (config/db-based-graph? (state/get-current-repo)) ; memory fs
-        (p/let [binary (fs/read-file repo-dir path {})
-                blob (js/Blob. (array binary) (clj->js {:type "image"}))]
-          (when blob (js/URL.createObjectURL blob)))
-
-        :else ;; nfs
-        (let [handle-path (str "handle/" full-path)
-              cached-url  (get @*assets-url-cache (keyword handle-path))]
-          (if cached-url
-            (p/resolved cached-url)
-            ;; Loading File from handle cache
-            ;; Use await file handle, to ensure all handles are loaded.
-            (p/let [handle (nfs/await-get-nfs-file-handle repo handle-path)
-                    file   (and handle (.getFile handle))]
-              (when file
-                (p/let [url (js/URL.createObjectURL file)]
-                  (swap! *assets-url-cache assoc (keyword handle-path) url)
-                  url)))))))))
-
 (defn delete-asset-of-block!
   [{:keys [repo href full-text block-id local? delete-local?] :as _opts}]
   (let [block (db-model/query-block-by-uuid block-id)

+ 19 - 15
src/main/frontend/handler/ui.cljs

@@ -1,22 +1,23 @@
 (ns ^:no-doc frontend.handler.ui
-  (:require [cljs-time.core :refer [plus days weeks]]
+  (:require [cljs-time.core :refer [days plus weeks]]
+            [clojure.string :as string]
             [dommy.core :as dom]
-            [frontend.util :as util]
+            [electron.ipc :as ipc]
+            [frontend.config :as config]
             [frontend.db :as db]
             [frontend.db.model :as db-model]
-            [frontend.config :as config]
-            [frontend.state :as state]
-            [frontend.storage :as storage]
+            [frontend.db.react :as react]
             [frontend.fs :as fs]
+            [frontend.handler.assets :as assets-handler]
             [frontend.loader :refer [load]]
+            [frontend.state :as state]
+            [frontend.storage :as storage]
+            [frontend.util :as util]
             [goog.dom :as gdom]
             [goog.object :as gobj]
-            [clojure.string :as string]
-            [rum.core :as rum]
-            [electron.ipc :as ipc]
-            [promesa.core :as p]
             [logseq.common.path :as path]
-            [frontend.db.react :as react]))
+            [promesa.core :as p]
+            [rum.core :as rum]))
 
 ;; sidebars
 (def *right-sidebar-resized-at (atom (js/Date.now)))
@@ -105,11 +106,14 @@
 
 (defn add-style-if-exists!
   []
-  (when-let [style (or
-                    (state/get-custom-css-link)
-                    (some-> (db-model/get-custom-css)
-                            (config/expand-relative-assets-path)))]
-    (util/add-style! style)))
+  (when-let [style (or (state/get-custom-css-link)
+                       (db-model/get-custom-css))]
+    (if (config/db-based-graph? (state/get-current-repo))
+      (p/let [style (assets-handler/<expand-assets-links-for-db-graph style)]
+        (util/add-style! style))
+      (some-> (config/expand-relative-assets-path style)
+              (util/add-style!)))))
+
 (defn reset-custom-css!
   []
   (when-let [el-style (gdom/getElement "logseq-custom-theme-id")]

+ 6 - 6
src/main/logseq/sdk/assets.cljs

@@ -1,13 +1,13 @@
 (ns logseq.sdk.assets
-  (:require [electron.ipc :as ipc]
-            [cljs-bean.core :as bean]
-            [promesa.core :as p]
-            [frontend.handler.editor :as editor-handler]
+  (:require [cljs-bean.core :as bean]
+            [electron.ipc :as ipc]
             [frontend.extensions.pdf.assets :as pdf-assets]
+            [frontend.handler.assets :as assets-handler]
             [frontend.state :as state]
-            [frontend.util :as util]))
+            [frontend.util :as util]
+            [promesa.core :as p]))
 
-(def ^:export make_url editor-handler/make-asset-url)
+(def ^:export make_url assets-handler/make-asset-url)
 
 (defn ^:export list_files_of_current_graph
   [^js exts]