diff --git a/src/main/frontend/extensions/html_parser.cljs b/src/main/frontend/extensions/html_parser.cljs index f354f5561f..306f88b927 100644 --- a/src/main/frontend/extensions/html_parser.cljs +++ b/src/main/frontend/extensions/html_parser.cljs @@ -245,7 +245,7 @@ " |") (_ :guard #(contains? #{:aside :center :figure :figcaption :fieldset :footer :header} %)) - (export-hiccup x) + (throw (js/Error. (str "HTML->Hiccup: " tag " not supported yet"))) :ul (map-join children :list? true) :ol (map-join children :list? true) @@ -280,12 +280,19 @@ (goog.string.unescapeEntities f) f)) hiccup)) +(defn- remove-ending-dash-lines + [s] + (if (string? s) + (string/replace s #"(\n*-\s*\n*)*$" "") + s)) + (defn convert [format html] (when-not (string/blank? html) (let [hiccup (hickory/as-hiccup (hickory/parse html)) - decoded-hiccup (html-decode-hiccup hiccup)] - (hiccup->doc format decoded-hiccup)))) + decoded-hiccup (html-decode-hiccup hiccup) + result (hiccup->doc format decoded-hiccup)] + (remove-ending-dash-lines result)))) (comment ;; | Syntax | Description | Test Text |`` diff --git a/src/main/frontend/fs/sync.cljs b/src/main/frontend/fs/sync.cljs index eaa4f59483..5ac0dca41a 100644 --- a/src/main/frontend/fs/sync.cljs +++ b/src/main/frontend/fs/sync.cljs @@ -1650,12 +1650,12 @@ :else (do - (prn "[diff-merge]no base found, use empty content as base, avoid loosing data") + (prn "[diff-merge]no base found, failback") (p/let [current-content (-> (fs/read-file repo-dir current-change-file) (p/catch (fn [_] nil))) current-content (or current-content "") incoming-content (fs/read-file repo-dir incoming-file) - merged-content (diff-merge/three-way-merge "" current-content incoming-content format)] + merged-content (diff-merge/three-way-merge current-content current-content incoming-content format)] (if (= incoming-content merged-content) (p/do! (fs/copy! repo diff --git a/src/main/frontend/handler/paste.cljs b/src/main/frontend/handler/paste.cljs index e5e57cfc66..0d8da2f878 100644 --- a/src/main/frontend/handler/paste.cljs +++ b/src/main/frontend/handler/paste.cljs @@ -126,7 +126,7 @@ (get-whiteboard-tldr-from-text html)) ;; text should always be prepared block-ref generated in tldr text) - {:keys [value selection] :as selection-and-format} (editor-handler/get-selection-and-format) + {:keys [selection] :as selection-and-format} (editor-handler/get-selection-and-format) text-url? (gp-util/url? text) selection-url? (gp-util/url? selection)] (cond @@ -139,9 +139,8 @@ (and text-url? selection-url?)) (replace-text-f text) - ;; Pastes a formatted link over selected text - (and (or text-url? - (and value (gp-util/url? (string/trim value)))) + ;; Paste a formatted link over selected text or paste text over a selected formatted link + (and (or text-url? selection-url?) (not (string/blank? (util/get-selected-text)))) (editor-handler/html-link-format! text) @@ -248,7 +247,7 @@ (cond (and (string/blank? text) (string/blank? html)) ;; When both text and html are blank, paste file if exists. - ;; NOTE: util/stop is not called here if no file is provided, + ;; NOTE: util/stop is not called here if no file is provided, ;; so the default paste behavior of the native platform will be used. (when has-files? (paste-file-if-exists id e)) diff --git a/src/test/frontend/handler/paste_test.cljs b/src/test/frontend/handler/paste_test.cljs index c03046e33c..e769273c98 100644 --- a/src/test/frontend/handler/paste_test.cljs +++ b/src/test/frontend/handler/paste_test.cljs @@ -122,6 +122,28 @@ (is (= expected-paste result)) (reset)))))) +(deftest-async editor-on-paste-with-text-over-link + (testing "Paste text over a selected formatted link" + (let [actual-text (atom nil) + clipboard "logseq" + selected-text "https://logseq.com" + block-content (str selected-text " is awesome") + expected-paste "[logseq](https://logseq.com) is awesome"] + (test-helper/with-reset + reset + [;; paste-copied-blocks-or-text mocks below + util/stop (constantly nil) + util/get-selected-text (constantly selected-text) + editor-handler/get-selection-and-format + (constantly {:selection-start 0 :selection-end (count selected-text) + :selection selected-text :format :markdown :value block-content}) + state/set-edit-content! (fn [_ new-value] (reset! actual-text new-value)) + cursor/move-cursor-to (constantly nil)] + (p/let [_ ((paste-handler/editor-on-paste! nil) + #js {:clipboardData #js {:getData (constantly clipboard)}})] + (is (= expected-paste @actual-text)) + (reset)))))) + (deftest-async editor-on-paste-with-selected-text-and-special-link (testing "Formatted paste with special link on selected text pastes a formatted link" (let [actual-text (atom nil)