From e9ea5ef34cc01479913918c3057a9a67525b31f5 Mon Sep 17 00:00:00 2001 From: rcmerci Date: Fri, 15 May 2026 16:54:49 +0800 Subject: [PATCH 1/3] Fix sqlite FTS quote parsing --- src/main/frontend/worker/search.cljs | 2 +- src/test/frontend/worker/search_test.cljs | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/frontend/worker/search.cljs b/src/main/frontend/worker/search.cljs index 2c0f19fac7..6fef7cfad3 100644 --- a/src/main/frontend/worker/search.cljs +++ b/src/main/frontend/worker/search.cljs @@ -342,7 +342,7 @@ DROP TRIGGER IF EXISTS blocks_au; (and (re-find #"[^\w\s]" q) (or (not (some #(string/includes? match-input %) ["AND" "OR" "NOT"])) (string/includes? q "/"))) ; punctuations - (str "\"" match-input "\"*") + (str "\"" (string/replace match-input "\"" "\"\"") "\"*") (not= q match-input) (string/replace match-input "," "") :else diff --git a/src/test/frontend/worker/search_test.cljs b/src/test/frontend/worker/search_test.cljs index 8c499d369d..b09dff500e 100644 --- a/src/test/frontend/worker/search_test.cljs +++ b/src/test/frontend/worker/search_test.cljs @@ -209,6 +209,23 @@ (is (some? result)) (is (empty? result))))) +(deftest search-blocks-escapes-quotes-for-fts + (testing "user quote characters are escaped before SQLite FTS receives them" + (let [fts-binds (atom []) + db #js {:exec (fn [opts] + (let [sql (aget opts "sql") + bind (js->clj (aget opts "bind"))] + (when (string/includes? sql "title match ?") + (swap! fts-binds conj (first bind))) + #js []))}] + (with-redefs [search/combine-results (fn [_db results] results) + search/search-result->block-result + (fn [_conn _q _code-class _option result] + result)] + (is (empty? (search/search-blocks (atom :large-db) db "\"" {:limit 10}))) + (is (empty? (search/search-blocks (atom :large-db) db "foo \"bar" {:limit 10}))) + (is (= ["\"\"\"\"*" "\"foo \"\"bar\"*"] @fts-binds)))))) + (deftest search-blocks-large-graph-benchmark-regression (testing "cmd-k and autocomplete queries must not scan the full Datascript graph while typing" (let [calls (atom []) From 302f79805220cefab26da66eae1e18c69e165afb Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Fri, 15 May 2026 19:52:47 +0800 Subject: [PATCH 2/3] fix(editor): open missing journal links from shortcut fix https://github.com/logseq/db-test/issues/879 --- src/main/frontend/handler/editor.cljs | 15 ++++- src/test/frontend/handler/editor_test.cljs | 66 ++++++++++++++++++++++ 2 files changed, 78 insertions(+), 3 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index d8ed2a0077..47658a3905 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -1094,6 +1094,17 @@ (let [value (gobj/get input "value")] (extract-nearest-link-from-text value pos)))))))) +(defn- (follow-page-link-result {:page-title "Project" + :existing-page? true}) + (p/then + (fn [{:keys [events redirects]}] + (is (empty? events)) + (is (= [["Project"]] redirects)) + (done)))))) + +(deftest follow-link-under-cursor-creates-missing-page-test + (async done + (-> (follow-page-link-result {:page-title "May 15th, 2026" + :existing-page? false}) + (p/then + (fn [{:keys [events redirects]}] + (is (= [[:page/create "May 15th, 2026"]] events)) + (is (empty? redirects)) + (done)))))) + +(deftest follow-link-under-cursor-uses-worker-page-before-creating-test + (async done + (-> (follow-page-link-result {:page-title "May 15th, 2026" + :existing-page? false + :worker-page? true}) + (p/then + (fn [{:keys [events redirects]}] + (is (empty? events)) + (is (= [["May 15th, 2026"]] redirects)) + (done)))))) + (defn- keyup-handler "Spied version of editor/keyup-handler" [{:keys [value cursor-pos action commands] From 658e6725514a6ac5e089f256eec03d917588d0e0 Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 15 May 2026 20:29:04 +0800 Subject: [PATCH 3/3] fix(assets): improve handling of external and local asset URLs --- src/main/frontend/components/block.cljs | 31 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 3b81af0ea4..5a8472b92c 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -495,10 +495,14 @@ (rum/local nil ::src) [state config title href metadata full_text] (let [src (::src state) - ^js js-url (:link-js-url config) href (cond-> href - (nil? js-url) - (config/get-local-asset-absolute-path))] + (common-config/local-relative-asset? href) + (config/get-local-asset-absolute-path)) + ^js js-url (or (:link-js-url config) + (when (path/protocol-url? href) + (try + (js/URL. href) + (catch :default _ nil))))] (when (nil? @src) (-> (assets-handler//... - (path/path-join repo-dir (string/replace ext-url #"^[./]+" "")) - (path/path-join repo-dir (str "assets/" (:block/uuid asset-block) "." (name ext))))] - (js/window.apis.openPath file-fpath)))} + ext-url (:logseq.property.asset/external-url asset-block) + remote-ext-url? (and (not (string/blank? ext-url)) + (path/protocol-url? ext-url) + (not (common-config/local-protocol-asset? ext-url))) + local-ext-url? (and (not (string/blank? ext-url)) + (common-config/local-relative-asset? ext-url)) + file-fpath (if local-ext-url? + ;; Plugin-sourced asset stored under assets/storages//... + (path/path-join repo-dir (string/replace ext-url #"^[./]+" "")) + (path/path-join repo-dir (str "assets/" (:block/uuid asset-block) "." (name ext))))] + (if remote-ext-url? + (js/window.apis.openExternal ext-url) + (js/window.apis.openPath file-fpath))))} file-name]) :else