Browse Source

Merge branch 'feat/db' into refactor/dsl-query

Tienson Qin 1 year ago
parent
commit
03321f665b

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

@@ -462,7 +462,8 @@
           (swap! ignored-properties conj {:property prop :value val :schema (get property-changes prop)})
           (swap! ignored-properties conj {:property prop :value val :schema (get property-changes prop)})
           nil)
           nil)
         (do
         (do
-          (swap! upstream-properties assoc prop {:schema {:type :default}})
+          (swap! upstream-properties assoc prop {:schema {:type :default}
+                                                 :from-type (:from type-change)})
           (swap! property-schemas assoc prop {:type :default})
           (swap! property-schemas assoc prop {:type :default})
           (get properties-text-values prop)))
           (get properties-text-values prop)))
 
 
@@ -880,7 +881,7 @@
 
 
 (defn- build-upstream-properties-tx-for-default
 (defn- build-upstream-properties-tx-for-default
   "Builds upstream-properties-tx for properties that change to :default type"
   "Builds upstream-properties-tx for properties that change to :default type"
-  [db prop property-ident block-properties-text-values]
+  [db prop property-ident from-prop-type block-properties-text-values]
   (let [get-pvalue-content (fn get-pvalue-content [block-uuid prop']
   (let [get-pvalue-content (fn get-pvalue-content [block-uuid prop']
                              (or (get-in block-properties-text-values [block-uuid prop'])
                              (or (get-in block-properties-text-values [block-uuid prop'])
                                  (throw (ex-info (str "No :block/text-properties-values found when changing property values: " (pr-str block-uuid))
                                  (throw (ex-info (str "No :block/text-properties-values found when changing property values: " (pr-str block-uuid))
@@ -898,11 +899,16 @@
         existing-blocks-tx
         existing-blocks-tx
         (mapcat (fn [m]
         (mapcat (fn [m]
                   (let [prop-value (get m property-ident)
                   (let [prop-value (get m property-ident)
+                        ;; Don't delete property values from these types b/c those pages are needed
+                        ;; for refs and may have content
+                        retract-tx (if (#{:node :date} from-prop-type)
+                                     [[:db/retract (:db/id m) property-ident]]
+                                     (mapv #(vector :db/retractEntity (:db/id %))
+                                           (if (sequential? prop-value) prop-value [prop-value])))
                         prop-value-content (get-pvalue-content (:block/uuid m) prop)
                         prop-value-content (get-pvalue-content (:block/uuid m) prop)
                         new-value (db-property-build/build-property-value-block
                         new-value (db-property-build/build-property-value-block
                                    m {:db/ident property-ident} prop-value-content)]
                                    m {:db/ident property-ident} prop-value-content)]
-                    (into (mapv #(vector :db/retractEntity (:db/id %))
-                                (if (sequential? prop-value) prop-value [prop-value]))
+                    (into retract-tx
                           [new-value
                           [new-value
                            {:block/uuid (:block/uuid m)
                            {:block/uuid (:block/uuid m)
                             property-ident [:block/uuid (:block/uuid new-value)]}])))
                             property-ident [:block/uuid (:block/uuid new-value)]}])))
@@ -921,11 +927,11 @@
           _ (log-fn :props-upstream-to-change upstream-properties)
           _ (log-fn :props-upstream-to-change upstream-properties)
           txs
           txs
           (mapcat
           (mapcat
-           (fn [[prop {:keys [schema]}]]
+           (fn [[prop {:keys [schema from-type]}]]
              (let [prop-ident (get-ident all-idents prop)
              (let [prop-ident (get-ident all-idents prop)
                    upstream-tx
                    upstream-tx
                    (when (= :default (:type schema))
                    (when (= :default (:type schema))
-                     (build-upstream-properties-tx-for-default db prop prop-ident block-properties-text-values))
+                     (build-upstream-properties-tx-for-default db prop prop-ident from-type block-properties-text-values))
                    property-pages-tx [{:db/ident prop-ident :block/schema schema}]]
                    property-pages-tx [{:db/ident prop-ident :block/schema schema}]]
                ;; If we handle cardinality changes we would need to return these separately
                ;; If we handle cardinality changes we would need to return these separately
                ;; as property-pages would need to be transacted separately
                ;; as property-pages would need to be transacted separately

+ 13 - 3
deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs

@@ -41,7 +41,13 @@
               db)
               db)
          first)))
          first)))
 
 
-(defn- find-block-by-property [db property property-value]
+(defn- find-block-by-property [db property]
+  (d/q '[:find [(pull ?b [*]) ...]
+         :in $ ?prop %
+         :where (has-property ?b ?prop)]
+       db property (rules/extract-rules rules/db-query-dsl-rules [:has-property])))
+
+(defn- find-block-by-property-value [db property property-value]
   (->> (d/q '[:find [(pull ?b [*]) ...]
   (->> (d/q '[:find [(pull ?b [*]) ...]
               :in $ ?prop ?prop-value %
               :in $ ?prop ?prop-value %
               :where (property ?b ?prop ?prop-value)]
               :where (property ?b ?prop ?prop-value)]
@@ -308,7 +314,7 @@
               :logseq.property.table/ordered-columns [:block/title :user.property/prop-string :user.property/prop-num]
               :logseq.property.table/ordered-columns [:block/title :user.property/prop-string :user.property/prop-num]
               :logseq.property/query "(property :prop-string)"
               :logseq.property/query "(property :prop-string)"
               :block/tags [:logseq.class/Query]}
               :block/tags [:logseq.class/Query]}
-             (readable-properties @conn (find-block-by-property @conn :logseq.property/query "(property :prop-string)")))
+             (readable-properties @conn (find-block-by-property-value @conn :logseq.property/query "(property :prop-string)")))
           "simple query block has correct query properties")
           "simple query block has correct query properties")
       (is (= "For example, here's a query with title text:"
       (is (= "For example, here's a query with title text:"
              (:block/title (find-block-by-content @conn #"query with title text")))
              (:block/title (find-block-by-content @conn #"query with title text")))
@@ -359,7 +365,11 @@
             "existing :node property value correctly saved as :default with full text")
             "existing :node property value correctly saved as :default with full text")
         (is (= #{"[[Gabriel]] [[Jakob]]"}
         (is (= #{"[[Gabriel]] [[Jakob]]"}
                (:user.property/people (readable-properties @conn (find-block-by-content @conn #"pending block for :node"))))
                (:user.property/people (readable-properties @conn (find-block-by-content @conn #"pending block for :node"))))
-            "pending :node property value correctly saved as :default with full text")))
+            "pending :node property value correctly saved as :default with full text")
+        (is (some? (find-page-by-name @conn "Jakob"))
+            "Previous :node property value still exists")
+        (is (= 3 (count (find-block-by-property @conn :user.property/people)))
+            "Converted property has correct number of property values")))
 
 
     (testing "replacing refs in :block/title"
     (testing "replacing refs in :block/title"
       (is (= 2
       (is (= 2

+ 80 - 62
src/main/frontend/components/block.cljs

@@ -942,6 +942,13 @@
                 nil
                 nil
                 nil)))
                 nil)))
 
 
+(defn- img-audio-video?
+  [block]
+  (let [asset-type (some-> (:logseq.property.asset/type block) keyword)]
+    (or (contains? (common-config/img-formats) asset-type)
+        (contains? config/audio-formats asset-type)
+        (contains? config/video-formats asset-type))))
+
 (rum/defc page-reference < rum/reactive
 (rum/defc page-reference < rum/reactive
   "Component for page reference"
   "Component for page reference"
   [html-export? s {:keys [nested-link? show-brackets? id] :as config} label]
   [html-export? s {:keys [nested-link? show-brackets? id] :as config} label]
@@ -957,8 +964,12 @@
           config' (assoc config
           config' (assoc config
                          :label (mldoc/plain->text label)
                          :label (mldoc/plain->text label)
                          :contents-page? contents-page?
                          :contents-page? contents-page?
-                         :show-icon? true?)]
+                         :show-icon? true?)
+          asset? (some? (:logseq.property.asset/type block))]
       (cond
       (cond
+        (and asset? (img-audio-video? block))
+        (asset-cp config block)
+
         (string/ends-with? s ".excalidraw")
         (string/ends-with? s ".excalidraw")
         [:div.draw {:on-click (fn [e]
         [:div.draw {:on-click (fn [e]
                                 (.stopPropagation e))}
                                 (.stopPropagation e))}
@@ -1118,61 +1129,64 @@
               repo (state/get-current-repo)
               repo (state/get-current-repo)
               stop-inner-events? (= block-type :whiteboard-shape)]
               stop-inner-events? (= block-type :whiteboard-shape)]
           (if (and block (:block/title block))
           (if (and block (:block/title block))
-            (let [title [:span.block-ref
-                         (block-content (assoc config :block-ref? true :stop-events? stop-inner-events?)
-                                        block nil (:block/uuid block)
-                                        (:slide? config))]
-                  inner (cond
-                          label
-                          (->elem
-                           :span.block-ref
-                           (map-inline config label))
-                          :else
-                          title)]
-              [:div.block-ref-wrap.inline
-               {:data-type    (name (or block-type :default))
-                :data-hl-type hl-type
-                :on-pointer-down
-                (fn [^js/MouseEvent e]
-                  (if (util/right-click? e)
-                    (state/set-state! :block-ref/context {:block (:block config)
-                                                          :block-ref block-id})
-                    (when (and
-                           (or (gobj/get e "shiftKey")
-                               (not (.. e -target (closest ".blank"))))
-                           (not (util/right-click? e)))
-                      (util/stop e)
-
-                      (cond
-                        (gobj/get e "shiftKey")
-                        (state/sidebar-add-block!
-                         (state/get-current-repo)
-                         (:db/id block)
-                         :block-ref)
-
-                        (and (util/meta-key? e) (whiteboard-handler/inside-portal? (.-target e)))
-                        (whiteboard-handler/add-new-block-portal-shape!
-                         (:block/uuid block)
-                         (whiteboard-handler/closest-shape (.-target e)))
-
-                        :else
-                        (match [block-type (util/electron?)]
+            (let [content-cp (block-content (assoc config :block-ref? true :stop-events? stop-inner-events?)
+                                            block nil (:block/uuid block)
+                                            (:slide? config))
+                  display-type (:logseq.property.node/display-type block)]
+              (if (and display-type (not (contains? #{:quote :math} display-type)))
+                content-cp
+                (let [title [:span.block-ref content-cp]
+                      inner (cond
+                              label
+                              (->elem
+                               :span.block-ref
+                               (map-inline config label))
+                              :else
+                              title)]
+                  [:div.block-ref-wrap.inline
+                   {:data-type    (name (or block-type :default))
+                    :data-hl-type hl-type
+                    :on-pointer-down
+                    (fn [^js/MouseEvent e]
+                      (if (util/right-click? e)
+                        (state/set-state! :block-ref/context {:block (:block config)
+                                                              :block-ref block-id})
+                        (when (and
+                               (or (gobj/get e "shiftKey")
+                                   (not (.. e -target (closest ".blank"))))
+                               (not (util/right-click? e)))
+                          (util/stop e)
+
+                          (cond
+                            (gobj/get e "shiftKey")
+                            (state/sidebar-add-block!
+                             (state/get-current-repo)
+                             (:db/id block)
+                             :block-ref)
+
+                            (and (util/meta-key? e) (whiteboard-handler/inside-portal? (.-target e)))
+                            (whiteboard-handler/add-new-block-portal-shape!
+                             (:block/uuid block)
+                             (whiteboard-handler/closest-shape (.-target e)))
+
+                            :else
+                            (match [block-type (util/electron?)]
                           ;; pdf annotation
                           ;; pdf annotation
-                          [:annotation true] (pdf-assets/open-block-ref! block)
+                              [:annotation true] (pdf-assets/open-block-ref! block)
 
 
-                          [:whiteboard-shape true] (route-handler/redirect-to-page!
-                                                    (get-in block [:block/page :block/uuid]) {:block-id block-id})
+                              [:whiteboard-shape true] (route-handler/redirect-to-page!
+                                                        (get-in block [:block/page :block/uuid]) {:block-id block-id})
 
 
                           ;; default open block page
                           ;; default open block page
-                          :else (route-handler/redirect-to-page! id))))))}
-
-               (if (and (not (util/mobile?))
-                        (not (:preview? config))
-                        (not (:modal/show? @state/state))
-                        (nil? block-type))
-                 (block-reference-preview inner
-                                          {:repo repo :config config :id block-id})
-                 inner)])
+                              :else (route-handler/redirect-to-page! id))))))}
+
+                   (if (and (not (util/mobile?))
+                            (not (:preview? config))
+                            (not (:modal/show? @state/state))
+                            (nil? block-type))
+                     (block-reference-preview inner
+                                              {:repo repo :config config :id block-id})
+                     inner)])))
             (invalid-node-ref id))))
             (invalid-node-ref id))))
       (invalid-node-ref id))))
       (invalid-node-ref id))))
 
 
@@ -1798,7 +1812,7 @@
     ["Latex_Fragment" [display s]] ;display can be "Displayed" or "Inline"
     ["Latex_Fragment" [display s]] ;display can be "Displayed" or "Inline"
     (if html-export?
     (if html-export?
       (latex/html-export s false true)
       (latex/html-export s false true)
-      (latex/latex (str (d/squuid)) s false (not= display "Inline")))
+      (latex/latex s false (not= display "Inline")))
 
 
     [(:or "Target" "Radio_Target") s]
     [(:or "Target" "Radio_Target") s]
     [:a {:id s} s]
     [:a {:id s} s]
@@ -2195,15 +2209,19 @@
       (text-block-title (dissoc config :raw-title?) block)
       (text-block-title (dissoc config :raw-title?) block)
 
 
       (= "asset" (:block/type block))
       (= "asset" (:block/type block))
-      (asset-cp config block)
+      [:div.grid.grid-cols-1.justify-items-center
+       (asset-cp config block)
+       (when (img-audio-video? block)
+         [:div.text-xs.opacity-60.mt-1
+          (text-block-title (dissoc config :raw-title?) block)])]
 
 
       (= :code node-display-type)
       (= :code node-display-type)
       [:div.flex.flex-1.w-full
       [:div.flex.flex-1.w-full
-       (src-cp (assoc config :block block) {:language (:logseq.property.code/lang block)})]
+       (src-cp (assoc config :code-block block) {:language (:logseq.property.code/lang block)})]
 
 
       ;; TODO: switched to https://cortexjs.io/mathlive/ for editing
       ;; TODO: switched to https://cortexjs.io/mathlive/ for editing
       (= :math node-display-type)
       (= :math node-display-type)
-      (latex/latex (str (:container-id config) "-" (:db/id block)) (:block/title block) true false)
+      (latex/latex (:block/title block) true false)
 
 
       (and query?
       (and query?
            collapsed?
            collapsed?
@@ -3159,7 +3177,7 @@
         (cond
         (cond
           (and advanced-query? (not collapsed?))
           (and advanced-query? (not collapsed?))
           [:div.flex.flex-1.my-1 {:style {:margin-left 42}}
           [:div.flex.flex-1.my-1 {:style {:margin-left 42}}
-           (src-cp (assoc config :block query)
+           (src-cp (assoc config :code-block query)
                    {:language "clojure"})]
                    {:language "clojure"})]
 
 
           (and (not advanced-query?) (not collapsed?))
           (and (not advanced-query?) (not collapsed?))
@@ -3613,7 +3631,7 @@
 
 
 (rum/defc src-cp < rum/static
 (rum/defc src-cp < rum/static
   [config options]
   [config options]
-  (let [block (:block config)
+  (let [block (or (:code-block config) (:block config))
         container-id (:container-id config)
         container-id (:container-id config)
         *mode-ref (rum/use-ref nil)
         *mode-ref (rum/use-ref nil)
         *actions-ref (rum/use-ref nil)]
         *actions-ref (rum/use-ref nil)]
@@ -3753,7 +3771,7 @@
       ["Math" s]
       ["Math" s]
       (if html-export?
       (if html-export?
         (latex/html-export s true true)
         (latex/html-export s true true)
-        (latex/latex (str (d/squuid)) s true true))
+        (latex/latex s true true))
       ["Example" l]
       ["Example" l]
       [:pre.pre-wrap-white-space
       [:pre.pre-wrap-white-space
        (join-lines l)]
        (join-lines l)]
@@ -3783,7 +3801,7 @@
         (latex/html-export content true false)
         (latex/html-export content true false)
         (if (config/db-based-graph? (state/get-current-repo))
         (if (config/db-based-graph? (state/get-current-repo))
           [:div.warning "'#+BEGIN_EXPORT latex' is deprecated. Use '/Math block' command instead."]
           [:div.warning "'#+BEGIN_EXPORT latex' is deprecated. Use '/Math block' command instead."]
-          (latex/latex (str (d/squuid)) content true false)))
+          (latex/latex content true false)))
 
 
       ["Custom" "query" _options _result content]
       ["Custom" "query" _options _result content]
       (if (config/db-based-graph? (state/get-current-repo))
       (if (config/db-based-graph? (state/get-current-repo))
@@ -3832,12 +3850,12 @@
       (let [content (latex-environment-content name option content)]
       (let [content (latex-environment-content name option content)]
         (if html-export?
         (if html-export?
           (latex/html-export content true true)
           (latex/html-export content true true)
-          (latex/latex (str (d/squuid)) content true true)))
+          (latex/latex content true true)))
 
 
       ["Displayed_Math" content]
       ["Displayed_Math" content]
       (if html-export?
       (if html-export?
         (latex/html-export content true true)
         (latex/html-export content true true)
-        (latex/latex (str (d/squuid)) content true true))
+        (latex/latex content true true))
 
 
       ["Footnote_Definition" name definition]
       ["Footnote_Definition" name definition]
       (let [id (util/url-encode name)]
       (let [id (util/url-encode name)]

+ 2 - 3
src/main/frontend/components/shortcut_help.cljs

@@ -75,7 +75,7 @@
                   :link [:a {:href "https://www.example.com"} "Link"]
                   :link [:a {:href "https://www.example.com"} "Link"]
                   :del [:del (t :strikethrough)]
                   :del [:del (t :strikethrough)]
                   :mark [:mark (t :highlight)]
                   :mark [:mark (t :highlight)]
-                  :latex (latex/latex "help-latex" "E = mc^2" true false)
+                  :latex (latex/latex "E = mc^2" true false)
                   :code [:code (t :code)]
                   :code [:code (t :code)]
                   :pre (highlight/highlight "help-highlight" {:data-lang "clojure"} "(println \"Hello world!\")")
                   :pre (highlight/highlight "help-highlight" {:data-lang "clojure"} "(println \"Hello world!\")")
                   :img [:img {:style {:float "right" :width 32 :height 32}
                   :img [:img {:style {:float "right" :width 32 :height 32}
@@ -92,8 +92,7 @@
              [:tr
              [:tr
               [:td.text-left [(if (= :pre name) :pre :code) (get raw name)]]
               [:td.text-left [(if (= :pre name) :pre :code) (get raw name)]]
               [:td.text-right (get rendered name)]])
               [:td.text-right (get rendered name)]])
-        list)]]))
-
+           list)]]))
 
 
 (rum/defc shortcut-page
 (rum/defc shortcut-page
   [{:keys [show-title?]
   [{:keys [show-title?]

+ 27 - 28
src/main/frontend/extensions/code.cljs

@@ -390,7 +390,7 @@
   [config]
   [config]
   (p/do!
   (p/do!
    (code-handler/save-code-editor!)
    (code-handler/save-code-editor!)
-   (when-let [block (:block config)]
+   (when-let [block (or (:code-block config) (:block config))]
      (let [block (db/entity [:block/uuid (:block/uuid block)])]
      (let [block (db/entity [:block/uuid (:block/uuid block)])]
        (state/set-state! :editor/raw-mode-block block)
        (state/set-state! :editor/raw-mode-block block)
        (editor-handler/edit-block! block :max {:save-code-editor? false})))))
        (editor-handler/edit-block! block :max {:save-code-editor? false})))))
@@ -399,10 +399,8 @@
   [state]
   [state]
   (let [[config id attr _code theme user-options] (:rum/args state)
   (let [[config id attr _code theme user-options] (:rum/args state)
         edit-block (:block config)
         edit-block (:block config)
+        code-block (:code-block config)
         config-file? (= (:file-path config) "logseq/config.edn")
         config-file? (= (:file-path config) "logseq/config.edn")
-        default-open? (and (:editor/code-mode? @state/state)
-                           (= (:block/uuid edit-block)
-                              (get-in config [:block :block/uuid])))
         _ (state/set-state! :editor/code-mode? false)
         _ (state/set-state! :editor/code-mode? false)
         original-mode (get attr :data-lang)
         original-mode (get attr :data-lang)
         *editor-ref (get attr :editor-ref)
         *editor-ref (get attr :editor-ref)
@@ -449,13 +447,16 @@
             *cursor-prev (volatile! nil)
             *cursor-prev (volatile! nil)
             *cursor-curr (volatile! nil)
             *cursor-curr (volatile! nil)
             update-cursor-state! (fn []
             update-cursor-state! (fn []
-                                   (let [pos (.getCursor editor)
-                                         pos (bean/->clj (js/JSON.parse (js/JSON.stringify pos)))
-                                         pos (select-keys pos [:line :ch])]
+                                   (let [start-pos (.getCursor editor true)
+                                         end-pos (.getCursor editor false)
+                                         start-pos' (bean/->clj (js/JSON.parse (js/JSON.stringify start-pos)))
+                                         end-pos' (bean/->clj (js/JSON.parse (js/JSON.stringify end-pos)))
+                                         range {:start (select-keys start-pos' [:line :ch])
+                                                :end (select-keys end-pos' [:line :ch])}]
                                      (if (not @*cursor-prev)
                                      (if (not @*cursor-prev)
-                                       (vreset! *cursor-prev pos)
+                                       (vreset! *cursor-prev range)
                                        (vreset! *cursor-prev @*cursor-curr))
                                        (vreset! *cursor-prev @*cursor-curr))
-                                     (vreset! *cursor-curr pos)))]
+                                     (vreset! *cursor-curr range)))]
         (gobj/set textarea-ref codemirror-ref-name editor)
         (gobj/set textarea-ref codemirror-ref-name editor)
         (when (= mode "calc")
         (when (= mode "calc")
           (.on editor "change" (fn [_cm _e]
           (.on editor "change" (fn [_cm _e]
@@ -473,9 +474,9 @@
                              (vreset! *cursor-prev nil)))
                              (vreset! *cursor-prev nil)))
         (.on editor "focus" (fn [_e]
         (.on editor "focus" (fn [_e]
                               (when (and
                               (when (and
-                                     (contains? #{:code} (:logseq.property.node/display-type edit-block))
+                                     (contains? #{:code} (:logseq.property.node/display-type code-block))
                                      (not= (:block/uuid edit-block) (:block/uuid (state/get-edit-block))))
                                      (not= (:block/uuid edit-block) (:block/uuid (state/get-edit-block))))
-                                (editor-handler/edit-block! edit-block :max))
+                                (editor-handler/edit-block! (or code-block edit-block) :max {:container-id (:container-id config)}))
                               (state/set-editing-block-dom-id! (:block-parent-id config))
                               (state/set-editing-block-dom-id! (:block-parent-id config))
                               (state/set-block-component-editing-mode! true)
                               (state/set-block-component-editing-mode! true)
                               (state/set-state! :editor/code-block-context
                               (state/set-state! :editor/code-block-context
@@ -489,31 +490,31 @@
                                                      shifted? (.-shiftKey e)]
                                                      shifted? (.-shiftKey e)]
                                                  (cond
                                                  (cond
                                                    (contains? #{"ArrowLeft" "ArrowRight"} key-code)
                                                    (contains? #{"ArrowLeft" "ArrowRight"} key-code)
-                                                   (let [direction (if (= "ArrowLeft" key-code) :left :right)
-                                                         line (when-let [line (:line @*cursor-curr)]
-                                                                (.getLine (.-doc editor) line))]
+                                                   (let [direction (if (= "ArrowLeft" key-code) :left :right)]
                                                      (when (and (= @*cursor-prev @*cursor-curr)
                                                      (when (and (= @*cursor-prev @*cursor-curr)
                                                                 (or (and direction (nil? @*cursor-curr))
                                                                 (or (and direction (nil? @*cursor-curr))
                                                                     (case direction
                                                                     (case direction
-                                                                      :left (and (zero? (:line @*cursor-curr))
-                                                                                 (zero? (:ch  @*cursor-curr)))
-                                                                      :right (and (= (:line @*cursor-curr) (.lastLine editor))
-                                                                                  (= (count line) (:ch @*cursor-curr)))
+                                                                      :left (and (zero? (:line (:start @*cursor-curr)))
+                                                                                 (zero? (:ch  (:start @*cursor-curr))))
+                                                                      :right (let [line (when-let [line (:line (:end @*cursor-curr))]
+                                                                                          (.getLine (.-doc editor) line))]
+                                                                               (and (= (:line (:end @*cursor-curr)) (.lastLine editor))
+                                                                                    (= (:ch (:end @*cursor-curr)) (count line))))
                                                                       false)))
                                                                       false)))
                                                        (editor-handler/move-to-block-when-cross-boundary direction {}))
                                                        (editor-handler/move-to-block-when-cross-boundary direction {}))
                                                      (update-cursor-state!))
                                                      (update-cursor-state!))
 
 
                                                    (contains? #{"ArrowUp" "ArrowDown"} key-code)
                                                    (contains? #{"ArrowUp" "ArrowDown"} key-code)
-                                                   (let [direction (if (= "ArrowUp" key-code) :up :down)
-                                                         line (when-let [line (:line @*cursor-curr)]
-                                                                (.getLine (.-doc editor) line))]
+                                                   (let [direction (if (= "ArrowUp" key-code) :up :down)]
                                                      (when (and (= @*cursor-prev @*cursor-curr)
                                                      (when (and (= @*cursor-prev @*cursor-curr)
                                                                 (or (and direction (nil? @*cursor-curr))
                                                                 (or (and direction (nil? @*cursor-curr))
                                                                     (case direction
                                                                     (case direction
-                                                                      :up (and (zero? (:line @*cursor-curr))
-                                                                               (zero? (:ch  @*cursor-curr)))
-                                                                      :down (and (= (:line @*cursor-curr) (.lastLine editor))
-                                                                                 (= (count line) (:ch @*cursor-curr)))
+                                                                      :up (and (zero? (:line (:start @*cursor-curr)))
+                                                                               (zero? (:ch  (:start @*cursor-curr))))
+                                                                      :down (let [line (when-let [line (:line (:end @*cursor-curr))]
+                                                                                         (.getLine (.-doc editor) line))]
+                                                                              (and (= (:line (:end @*cursor-curr)) (.lastLine editor))
+                                                                                   (= (:ch (:end @*cursor-curr)) (count line))))
                                                                       false)))
                                                                       false)))
                                                        (editor-handler/move-cross-boundary-up-down
                                                        (editor-handler/move-cross-boundary-up-down
                                                         direction {:input textarea
                                                         direction {:input textarea
@@ -547,9 +548,7 @@
                            (fn [e]
                            (fn [e]
                              (.stopPropagation e)))
                              (.stopPropagation e)))
         (.save editor)
         (.save editor)
-        (.refresh editor)
-        (when default-open?
-          (.focus editor))))
+        (.refresh editor)))
     editor))
     editor))
 
 
 (defn- load-and-render!
 (defn- load-and-render!

+ 9 - 5
src/main/frontend/extensions/latex.cljs

@@ -16,7 +16,8 @@
 
 
 (defn render!
 (defn render!
   [state]
   [state]
-  (let [[id s _ display?] (:rum/args state)]
+  (let [[s _ display?] (:rum/args state)
+        id (:id state)]
     (try
     (try
       (when-let [elem (gdom/getElement id)]
       (when-let [elem (gdom/getElement id)]
         (js/katex.render s elem
         (js/katex.render s elem
@@ -56,11 +57,14 @@
   (js/setTimeout #(load-and-render! state) 10)
   (js/setTimeout #(load-and-render! state) 10)
   state)
   state)
 
 
-(rum/defc latex < rum/reactive
-  {:did-mount  state-&-load-and-render!
+(rum/defcs latex < rum/reactive
+  {:init (fn [state]
+           (assoc state :id (str (random-uuid))))
+   :did-mount  state-&-load-and-render!
    :did-update state-&-load-and-render!}
    :did-update state-&-load-and-render!}
-  [id s block? _display?]
-  (let [loading? (rum/react *loading?)]
+  [state s block? _display?]
+  (let [id (:id state)
+        loading? (rum/react *loading?)]
     (if loading?
     (if loading?
       (ui/loading)
       (ui/loading)
       (let [element (if block?
       (let [element (if block?

+ 1 - 1
src/main/frontend/handler/code.cljs

@@ -22,7 +22,7 @@
             value (gobj/get textarea "value")
             value (gobj/get textarea "value")
             default-value (or (.-v ds) (gobj/get textarea "defaultValue"))
             default-value (or (.-v ds) (gobj/get textarea "defaultValue"))
             repo (state/get-current-repo)
             repo (state/get-current-repo)
-            block (:block config)]
+            block (or (:code-block config) (:block config))]
         (when (not= value default-value)
         (when (not= value default-value)
           ;; update default value for the editor initial state
           ;; update default value for the editor initial state
           (set! ds -v value)
           (set! ds -v value)