mirror of
https://github.com/logseq/logseq.git
synced 2026-05-19 18:32:41 +00:00
Merge branch 'master' into feat/alias-redesign
This commit is contained in:
@@ -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/<make-asset-url href js-url)
|
||||
(p/then (fn [url]
|
||||
@@ -562,14 +566,19 @@
|
||||
{:on-click (fn [e]
|
||||
(util/stop e)
|
||||
(let [repo-dir (config/get-repo-dir repo)
|
||||
ext-url (:logseq.property.asset/external-url asset-block)
|
||||
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/<plugin-id>/...
|
||||
(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/<plugin-id>/...
|
||||
(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
|
||||
|
||||
@@ -1094,6 +1094,17 @@
|
||||
(let [value (gobj/get input "value")]
|
||||
(extract-nearest-link-from-text value pos))))))))
|
||||
|
||||
(defn- <follow-page-link!
|
||||
[page]
|
||||
(state/clear-edit!)
|
||||
(if (util/uuid-string? page)
|
||||
(route-handler/redirect-to-page! page)
|
||||
(p/let [page-entity (or (db/get-page page)
|
||||
(db-async/<get-block (state/get-current-repo) page {:children? false}))]
|
||||
(if page-entity
|
||||
(route-handler/redirect-to-page! page)
|
||||
(state/pub-event! [:page/create page])))))
|
||||
|
||||
(defn follow-link-under-cursor!
|
||||
[]
|
||||
(when-let [page (get-nearest-page-or-url)]
|
||||
@@ -1103,9 +1114,7 @@
|
||||
(save-current-block!)
|
||||
(if (re-find url-regex page)
|
||||
(js/window.open page)
|
||||
(do
|
||||
(state/clear-edit!)
|
||||
(route-handler/redirect-to-page! page)))))))
|
||||
(<follow-page-link! page))))))
|
||||
|
||||
(defn open-link-in-sidebar!
|
||||
[]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[frontend.db.async :as db-async]
|
||||
[frontend.db.model :as model]
|
||||
[frontend.handler.editor :as editor]
|
||||
[frontend.handler.route :as route-handler]
|
||||
[frontend.state :as state]
|
||||
[frontend.test.helper :as test-helper]
|
||||
[frontend.util :as util]
|
||||
@@ -59,6 +60,71 @@
|
||||
"[[https://github.com/logseq/logseq][logseq]] is #awesome :)" 0 editor/url-regex))
|
||||
"Finds url in org link correctly"))
|
||||
|
||||
(defn- follow-page-link-result
|
||||
[{:keys [page-title existing-page? worker-page?]}]
|
||||
(let [events (atom [])
|
||||
redirects (atom [])
|
||||
worker-page-uuid (random-uuid)
|
||||
input-id "edit-block-test"
|
||||
input #js {:value (str "Open [[" page-title "]]")}]
|
||||
(p/with-redefs [state/get-edit-block (constantly {:block/uuid (random-uuid)})
|
||||
state/get-edit-input-id (constantly input-id)
|
||||
gdom/getElement (fn [id]
|
||||
(when (= input-id id)
|
||||
input))
|
||||
cursor/pos (constantly 10)
|
||||
editor/save-current-block! (constantly nil)
|
||||
state/clear-editor-action! (constantly nil)
|
||||
state/clear-edit! (constantly nil)
|
||||
db/get-page (fn [title]
|
||||
(when (and existing-page? (= page-title title))
|
||||
{:block/title title
|
||||
:block/uuid (random-uuid)}))
|
||||
db-async/<get-block (fn [_repo title _opts]
|
||||
(p/resolved
|
||||
(when (and worker-page? (= page-title title))
|
||||
{:block/title title
|
||||
:block/uuid worker-page-uuid})))
|
||||
state/pub-event! (fn [event]
|
||||
(swap! events conj event)
|
||||
(p/resolved nil))
|
||||
route-handler/redirect-to-page! (fn [& args]
|
||||
(swap! redirects conj args))]
|
||||
(p/let [_ (editor/follow-link-under-cursor!)]
|
||||
{:events @events
|
||||
:redirects @redirects}))))
|
||||
|
||||
(deftest follow-link-under-cursor-opens-existing-page-test
|
||||
(async done
|
||||
(-> (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]
|
||||
|
||||
@@ -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 [])
|
||||
|
||||
Reference in New Issue
Block a user