Переглянути джерело

feat: swap out caret_pos imp

Weihua Lu 4 роки тому
батько
коміт
669dac7a09

+ 17 - 11
src/main/frontend/components/editor.cljs

@@ -308,7 +308,7 @@
                    (let [[id format] (:rum/args state)]
                      (add-watch editor-handler/*asset-pending-file ::pending-asset
                                 (fn [_ _ _ f]
-                                  (reset! *slash-caret-pos (util/get-caret-pos (gdom/getElement id)))
+                                  (reset! *slash-caret-pos (cursor/get-caret-pos (gdom/getElement id)))
                                   (editor-handler/upload-asset id #js[f] format editor-handler/*asset-uploading? true))))
                    state)
    :will-unmount (fn [state]
@@ -369,21 +369,27 @@
 
 
 (rum/defc mock-textarea
-  [content]
+  < rum/reactive
+  {:did-update
+   (fn [state]
+     (editor-handler/handle-last-input)
+     state)}
+  []
   [:div#mock-text
    {:style {:width "100%"
             :height "100%"
             :position "absolute"
-            :visibility "hidden"
+            ;; :visibility "hidden"
             :top 0
             :left 0}}
-   (map-indexed (fn [idx c]
-                  (if (= c "\n")
-                    [:span {:id (str "mock-text_" idx)
-                          :key idx} "0" [:br]]
-                    [:span {:id (str "mock-text_" idx)
-                            :key idx} c]))
-                (string/split (str content "0") ""))])
+   (for [[idx c] (map-indexed
+                  vector
+                  (string/split (str (state/sub [:editor/content (state/get-edit-input-id)]) "0") ""))]
+     (if (= c "\n")
+       [:span {:id (str "mock-text_" idx)
+               :key idx} "0" [:br]]
+       [:span {:id (str "mock-text_" idx)
+               :key idx} c]))])
 
 
 (rum/defcs box < rum/reactive
@@ -417,7 +423,7 @@
        :auto-focus        false
        :style             (get-editor-style heading-level)})
 
-     (mock-textarea content)
+     (mock-textarea)
 
      ;; TODO: how to render the transitions asynchronously?
      (transition-cp

+ 25 - 24
src/main/frontend/handler/editor.cljs

@@ -1532,12 +1532,12 @@
           "[["
           (do
             (commands/handle-step [:editor/search-page])
-            (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+            (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
           "(("
           (do
             (commands/handle-step [:editor/search-block :reference])
-            (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+            (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
           nil)))))
 
@@ -1848,7 +1848,6 @@
 (defn edit-box-on-change!
   [e block id]
   (let [value (util/evalue e)
-        current-pos (util/get-input-pos (gdom/getElement id))
         repo (or (:block/repo block)
                  (state/get-current-repo))]
     (state/set-edit-content! id value false)
@@ -1862,22 +1861,24 @@
                  (state/set-editor-op! :auto-save)
                  (save-current-block! {})
                  (state/set-editor-op! nil)))
-             500))
-    (let [input (gdom/getElement id)
-          native-e (gobj/get e "nativeEvent")
-          last-input-char (util/nth-safe value (dec current-pos))]
-      (case last-input-char
-        "/"
-        ;; TODO: is it cross-browser compatible?
-        (when (not= (gobj/get native-e "inputType") "insertFromPaste")
-          (when-let [matched-commands (seq (get-matched-commands input))]
-            (reset! commands/*slash-caret-pos (util/get-caret-pos input))
-            (reset! commands/*show-commands true)))
-        "<"
-        (when-let [matched-commands (seq (get-matched-block-commands input))]
-          (reset! commands/*angle-bracket-caret-pos (util/get-caret-pos input))
-          (reset! commands/*show-block-commands true))
-        nil))))
+             500))))
+
+(defn handle-last-input []
+  (let [input           (state/get-input)
+        pos             (cursor/pos input)
+        last-input-char (util/nth-safe (.-value input) (dec pos))]
+    (case last-input-char
+      "/"
+      ;; TODO: is it cross-browser compatible?
+      ;; (not= (gobj/get native-e "inputType") "insertFromPaste")
+      (when (seq (get-matched-commands input))
+        (reset! commands/*slash-caret-pos (cursor/get-caret-pos input))
+        (reset! commands/*show-commands true))
+      "<"
+      (when (seq (get-matched-block-commands input))
+        (reset! commands/*angle-bracket-caret-pos (cursor/get-caret-pos input))
+        (reset! commands/*show-block-commands true))
+      nil)))
 
 (defn block-on-chosen-handler
   [input id q format]
@@ -2515,11 +2516,11 @@
             (surround-by? input "[[" "]]")
             (do
               (commands/handle-step [:editor/search-page])
-              (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+              (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
             (surround-by? input "((" "))")
             (do
               (commands/handle-step [:editor/search-block :reference])
-              (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+              (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
             :else
             nil))
 
@@ -2530,7 +2531,7 @@
         (do
           (commands/handle-step [:editor/search-page-hashtag])
           (state/set-last-pos! (cursor/pos input))
-          (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+          (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
         (let [sym "$"]
           (and (= key sym)
@@ -2571,7 +2572,7 @@
           (commands/handle-step [:editor/input "[[]]" {:last-pattern "【【"
                                                        :backward-pos 2}])
           (commands/handle-step [:editor/search-page])
-          (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+          (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
         (when (and (or (= k "(") (= k "("))
                    (> current-pos 0)
@@ -2579,7 +2580,7 @@
           (commands/handle-step [:editor/input "(())" {:last-pattern "(("
                                                        :backward-pos 2}])
           (commands/handle-step [:editor/search-block :reference])
-          (reset! commands/*slash-caret-pos (util/get-caret-pos input)))
+          (reset! commands/*slash-caret-pos (cursor/get-caret-pos input)))
 
         (when (= c " ")
           (when (or (= (util/nth-safe value (dec (dec current-pos))) "#")

+ 0 - 12
src/main/frontend/util.cljc

@@ -5,7 +5,6 @@
    #?(:cljs [cljs-time.coerce :as tc])
    #?(:cljs [cljs-time.core :as t])
    #?(:cljs [dommy.core :as d])
-   #?(:cljs ["/frontend/caret_pos" :as caret-pos])
    #?(:cljs ["/frontend/selection" :as selection])
    #?(:cljs ["/frontend/utils" :as utils])
    #?(:cljs ["path" :as nodePath])
@@ -325,17 +324,6 @@
                  (.setEndPoint pre-caret-text-range "EndToEnd" text-range)
                  (gobj/get pre-caret-text-range "text")))))))))
 
-#?(:cljs
-   (defn get-caret-pos
-     [input]
-     (when input
-       (try
-         (let [pos ((gobj/get caret-pos "position") input)]
-           (set! pos -rect (.. input (getBoundingClientRect) (toJSON)))
-           (bean/->clj pos))
-         (catch js/Error e
-           (js/console.error e))))))
-
 (defn get-first-or-last-line-pos
   [input]
   (let [pos (.-selectionStart input)

+ 11 - 5
src/main/frontend/util/cursor.cljs

@@ -1,5 +1,6 @@
 (ns frontend.util.cursor
-  (:require [clojure.string :as string]
+  (:require [cljs-bean.core :as bean]
+            [clojure.string :as string]
             [frontend.util :as util]
             [goog.dom :as gdom]
             [goog.object :as gobj]))
@@ -20,20 +21,25 @@
              second
              int)})
 
-(defn- get-caret-pos
+(defn get-caret-pos
   [input]
-  (let [pos (.-selectionStart input)]
+  (let [pos (.-selectionStart input)
+        rect (bean/->clj (.. input (getBoundingClientRect) (toJSON)))]
     (try
       (-> (gdom/getElement "mock-text")
           gdom/getChildren
           array-seq
           (nth pos)
-          mock-char-pos)
-      (catch js/Error _e
+          mock-char-pos
+          (assoc :rect rect))
+      (catch :default _e
+        (js/console.log "index error" _e)
         {:pos pos
+         :rect rect
          :left js/Number.MAX_SAFE_INTEGER
          :top js/Number.MAX_SAFE_INTEGER}))))
 
+
 (defn pos [input]
   (when input
     (.-selectionStart input)))