From 5b119ea9905b5f91d1f264ba6c20b405e865563a Mon Sep 17 00:00:00 2001 From: Weihua Lu Date: Wed, 9 Jun 2021 11:48:19 +0800 Subject: [PATCH] fix: wrong cross boundary due to caret_pos bug --- src/main/frontend/handler/editor.cljs | 5 ++- src/main/frontend/util/cursor.cljs | 46 +++++++++++++++++++++------ 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index 942f8b618..a18922166 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -2249,7 +2249,6 @@ (defn keydown-up-down-handler [direction] (let [input (state/get-input) - line-height (util/get-textarea-line-height input) selected-start (.-selectionStart input) selected-end (.-selectionEnd input) up? (= direction :up) @@ -2260,8 +2259,8 @@ (util/set-caret-pos! input selected-start) (util/set-caret-pos! input selected-end)) - (or (and up? (util/textarea-cursor-first-row? input line-height)) - (and down? (util/textarea-cursor-end-row? input line-height))) + (or (and up? (cursor/textarea-cursor-first-row? input)) + (and down? (cursor/textarea-cursor-last-row? input))) (move-cross-boundrary-up-down direction) :else diff --git a/src/main/frontend/util/cursor.cljs b/src/main/frontend/util/cursor.cljs index 8efe582f0..c6dec97a1 100644 --- a/src/main/frontend/util/cursor.cljs +++ b/src/main/frontend/util/cursor.cljs @@ -1,7 +1,5 @@ (ns frontend.util.cursor - (:require ["/frontend/caret_pos" :as caret-pos] - [cljs-bean.core :as bean] - [clojure.string :as string] + (:require [clojure.string :as string] [frontend.util :as util] [goog.dom :as gdom] [goog.object :as gobj])) @@ -24,12 +22,17 @@ (defn- get-caret-pos [input] - (when input + (let [pos (.-selectionStart input)] (try - (let [pos ((gobj/get caret-pos "position") input)] - (bean/->clj pos)) - (catch js/Error e - (js/console.error e))))) + (-> (gdom/getElement "mock-text") + gdom/getChildren + array-seq + (nth pos) + mock-char-pos) + (catch js/Error _e + {:pos pos + :left js/Number.MAX_SAFE_INTEGER + :top js/Number.MAX_SAFE_INTEGER})))) (defn move-cursor-to [input n] (.setSelectionRange input n n)) @@ -92,14 +95,37 @@ inc))] (move-cursor-to input idx))) +(defn textarea-cursor-first-row? [input] + (let [elms (-> (gdom/getElement "mock-text") + gdom/getChildren + array-seq) + cursor (-> input + (get-caret-pos)) + tops (->> elms + (map mock-char-pos) + (map :top) + (distinct))] + (= (first tops) (:top cursor)))) + +(defn textarea-cursor-last-row? [input] + (let [elms (-> (gdom/getElement "mock-text") + gdom/getChildren + array-seq) + cursor (-> input + (get-caret-pos)) + tops (->> elms + (map mock-char-pos) + (map :top) + (distinct))] + (= (last tops) (:top cursor)))) + (defn- move-cursor-up-down [input direction] (let [elms (-> (gdom/getElement "mock-text") gdom/getChildren array-seq) cusor (-> input - (get-caret-pos) - (select-keys [:left :top :pos])) + (get-caret-pos)) chars (->> elms (map mock-char-pos) (group-by :top))