Просмотр исходного кода

fix: cursor jumps to the beginning when indent/outdent

It might be caused by the recent upgrading of rum, which brings back
the old render queue and batched updates.

https://github.com/tonsky/rum/commit/ae6a85028ef3849ad93396b0d779e75abbcbeacf
Tienson Qin 3 лет назад
Родитель
Сommit
096c69ffb8

+ 1 - 1
src/main/frontend/commands.cljs

@@ -496,7 +496,7 @@
 (defmethod handle-step :editor/restore-saved-cursor [[_]]
   (when-let [input-id (state/get-edit-input-id)]
     (when-let [current-input (gdom/getElement input-id)]
-      (cursor/move-cursor-to current-input (:editor/last-saved-cursor @state/state)))))
+      (cursor/move-cursor-to current-input (state/get-editor-last-pos)))))
 
 (defmethod handle-step :editor/clear-current-slash [[_ space?]]
   (when-let [input-id (state/get-edit-input-id)]

+ 5 - 5
src/main/frontend/components/editor.cljs

@@ -101,7 +101,7 @@
   "Embedded page searching popup"
   [id format]
   (when (state/sub :editor/show-page-search?)
-    (let [pos (:editor/last-saved-cursor @state/state)
+    (let [pos (state/get-editor-last-pos)
           input (gdom/getElement id)]
       (when input
         (let [current-pos (cursor/pos input)
@@ -191,7 +191,7 @@
                    state)}
   [state id _format]
   (when (state/sub :editor/show-block-search?)
-    (let [pos (:editor/last-saved-cursor @state/state)
+    (let [pos (state/get-editor-last-pos)
           input (gdom/getElement id)
           [id format] (:rum/args state)
           current-pos (cursor/pos input)
@@ -208,7 +208,7 @@
   {:will-unmount (fn [state] (reset! editor-handler/*selected-text nil) state)}
   [id _format]
   (when (state/sub :editor/show-template-search?)
-    (let [pos (:editor/last-saved-cursor @state/state)
+    (let [pos (state/get-editor-last-pos)
           input (gdom/getElement id)]
       (when input
         (let [current-pos (cursor/pos input)
@@ -234,7 +234,6 @@
    [:button.bottom-action
     {:on-mouse-down (fn [e]
                       (util/stop e)
-                      (state/set-state! :editor/pos (cursor/pos (state/get-input)))
                       (editor-handler/indent-outdent indent?))}
     (ui/icon icon {:style {:fontSize ui/icon-size}})]])
 
@@ -573,7 +572,8 @@
 
 (rum/defcs box < rum/reactive
   {:init (fn [state]
-           (assoc state ::heading-level (:heading-level (first (:rum/args state)))))
+           (assoc state ::heading-level (:heading-level (first (:rum/args state)))
+                  ::id (str (random-uuid))))
    :did-mount (fn [state]
                 (state/set-editor-args! (:rum/args state))
                 state)}

+ 16 - 19
src/main/frontend/handler/editor.cljs

@@ -177,10 +177,10 @@
   (when-let [node (gdom/getElement (str id))]
     (when-let [cursor-range (state/get-cursor-range)]
       (when-let [range cursor-range]
-        (let [pos (:editor/pos @state/state)
+        (let [pos (state/get-editor-last-pos)
               pos (or pos (diff/find-position markup range))]
           (cursor/move-cursor-to node pos)
-          (state/set-state! :editor/pos nil))))))
+          (state/clear-editor-last-pos!))))))
 
 (defn highlight-block!
   [block-uuid]
@@ -1897,7 +1897,7 @@
 
   (state/set-editor-show-input! nil)
 
-  (when-let [saved-cursor (get @state/state :editor/last-saved-cursor)]
+  (when-let [saved-cursor (state/get-editor-last-pos)]
     (when-let [input (gdom/getElement id)]
       (.focus input)
       (cursor/move-cursor-to input saved-cursor))))
@@ -1907,7 +1907,7 @@
   (when-let [id (state/get-edit-input-id)]
     (when-let [input (gdom/getElement id)]
       (let [current-pos (cursor/pos input)
-            pos (:editor/last-saved-cursor @state/state)
+            pos (state/get-editor-last-pos)
             edit-content (or (state/sub [:editor/content id]) "")]
         (or
          @*selected-text
@@ -1922,7 +1922,7 @@
              (not (wrapped-by? input "[[" "]]")))
     (when (get-search-q)
       (let [value (gobj/get input "value")
-            pos (:editor/last-saved-cursor @state/state)
+            pos (state/get-editor-last-pos)
             current-pos (cursor/pos input)
             between (util/safe-subs value (min pos current-pos) (max pos current-pos))]
         (when (and between
@@ -2786,8 +2786,10 @@
 (defn indent-outdent
   [indent?]
   (state/set-editor-op! :indent-outdent)
-  (let [{:keys [block]} (get-state)]
+  (let [pos (some-> (state/get-input) cursor/pos)
+        {:keys [block]} (get-state)]
     (when block
+      (state/set-editor-last-pos! pos)
       (let [current-node (outliner-core/block block)]
         (outliner-core/indent-outdent-nodes [current-node] indent?)))
     (state/set-editor-op! :nil)))
@@ -2797,16 +2799,11 @@
   (fn [e]
     (cond
       (state/editing?)
-      (let [input (state/get-input)
-            pos (cursor/pos input)]
-        (when (and (not (state/get-editor-show-input))
-                   (not (state/get-editor-show-date-picker?))
-                   (not (state/get-editor-show-template-search?)))
-          (util/stop e)
-          (indent-outdent (not (= :left direction)))
-          (and input pos
-               (when-let [input (state/get-input)]
-                 (cursor/move-cursor-to input pos)))))
+      (when (and (not (state/get-editor-show-input))
+                 (not (state/get-editor-show-date-picker?))
+                 (not (state/get-editor-show-template-search?)))
+        (util/stop e)
+        (indent-outdent (not (= :left direction))))
 
       (state/selection?)
       (do
@@ -2885,8 +2882,8 @@
         (do
           (commands/handle-step [:editor/search-page-hashtag])
           (if (= key "#")
-            (state/set-last-pos! (inc (cursor/pos input))) ;; In keydown handler, the `#` is not inserted yet.
-            (state/set-last-pos! (cursor/pos input)))
+            (state/set-editor-last-pos! (inc (cursor/pos input))) ;; In keydown handler, the `#` is not inserted yet.
+            (state/set-editor-last-pos! (cursor/pos input)))
           (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
         (let [sym "$"]
@@ -2937,7 +2934,7 @@
                   value (gobj/get input "value")
                   square-pos (string/last-index-of (subs value 0 (:pos orig-pos)) "[[")
                   pos (+ square-pos 2)
-                  _ (state/set-last-pos! pos)
+                  _ (state/set-editor-last-pos! pos)
                   pos (assoc orig-pos :pos pos)
                   command-step (if (= \# (util/nth-safe value (dec square-pos)))
                                  :editor/search-page-hashtag

+ 10 - 12
src/main/frontend/state.cljs

@@ -118,7 +118,6 @@
      :editor/block-dom-id                   nil
      :editor/set-timestamp-block            nil
      :editor/last-input-time                nil
-     :editor/pos                            nil
      :editor/document-mode?                 document-mode?
      :editor/args                           nil
      :editor/on-paste?                      false
@@ -524,16 +523,7 @@
        (when-let [input (gdom/getElement input-id)]
          (util/set-change-value input value)))
      (update-state! :editor/content (fn [m]
-                                      (assoc m input-id value)))
-     ;; followers
-     ;; (when-let [s (util/extract-uuid input-id)]
-     ;;   (let [input (gdom/getElement input-id)
-     ;;         leader-parent (util/rec-get-block-node input)
-     ;;         followers (->> (array-seq (js/document.getElementsByClassName s))
-     ;;                        (remove #(= leader-parent %)))]
-     ;;     (prn "followers: " (count followers))
-     ;;     ))
-     )))
+                                      (assoc m input-id value))))))
 
 (defn get-edit-input-id
   []
@@ -891,10 +881,18 @@
                       :cursor-range      nil
                       :editor/code-mode? true}))
 
-(defn set-last-pos!
+(defn set-editor-last-pos!
   [new-pos]
   (set-state! :editor/last-saved-cursor new-pos))
 
+(defn clear-editor-last-pos!
+  []
+  (set-state! :editor/last-saved-cursor nil))
+
+(defn get-editor-last-pos
+  []
+  (:editor/last-saved-cursor @state))
+
 (defn set-block-content-and-last-pos!
   [edit-input-id content new-pos]
   (when edit-input-id