Selaa lähdekoodia

refactor selection shortcut

Weihua Lu 4 vuotta sitten
vanhempi
sitoutus
d187b767b5

+ 2 - 26
src/main/frontend/components/content.cljs

@@ -247,27 +247,6 @@
 ;; TODO: content could be changed
 ;; Also, keyboard bindings should only be activated after
 ;; blocks were already selected.
-
-
-(defn- cut-blocks-and-clear-selections!
-  [copy?]
-  (editor-handler/cut-selection-blocks copy?)
-  (editor-handler/clear-selection! nil))
-
-(rum/defc hidden-selection < rum/reactive
-  (mixins/keyboard-mixin (util/->system-modifier "ctrl+c")
-                         (fn [_]
-                           (editor-handler/copy-selection-blocks)
-                           (editor-handler/clear-selection! nil)))
-  (mixins/keyboard-mixin (util/->system-modifier "ctrl+x")
-                         (fn [] (cut-blocks-and-clear-selections! true)))
-  (mixins/keyboard-mixin "backspace"
-                         (fn [] (cut-blocks-and-clear-selections! false)))
-  (mixins/keyboard-mixin "delete"
-                         (fn [] (cut-blocks-and-clear-selections! false)))
-  []
-  [:div#selection.hidden])
-
 (rum/defc hiccup-content < rum/static
   (mixins/event-mixin
    (fn [state]
@@ -278,8 +257,7 @@
                           (let [blocks (remove nil? blocks)
                                 blocks (remove #(d/has-class? % "dummy") blocks)]
                             (when (seq blocks)
-                              (doseq [block blocks]
-                                (d/add-class! block "selected noselect"))
+                              (util/select-highlight! blocks)
                               ;; TODO: We delay this so the following "click" event won't clear the selections.
                               ;; Needs more thinking.
                               (js/setTimeout #(state/set-selection-blocks! blocks)
@@ -391,8 +369,6 @@
         selected-blocks (state/sub :selection/blocks)]
     (if hiccup
       [:div
-       (hiccup-content id option)
-       (when (and in-selection-mode? (seq selected-blocks))
-         (hidden-selection))]
+       (hiccup-content id option)]
       (let [format (format/normalize format)]
         (non-hiccup-content id content on-click on-hide config format)))))

+ 0 - 1
src/main/frontend/components/editor.cljs

@@ -360,7 +360,6 @@
      (when config/mobile? (mobile-bar state id))
      (ui/ls-textarea
       {:id                id
-       :class             "mousetrap"
        :cacheMeasurements true
        :default-value     (or content "")
        :minRows           (if (state/enable-grammarly?) 2 1)

+ 37 - 50
src/main/frontend/handler/editor.cljs

@@ -797,10 +797,13 @@
    (util/copy-to-clipboard! (tap-clipboard block-id))))
 
 (defn exit-editing-and-set-selected-blocks!
-  [blocks]
-  (util/clear-selection!)
-  (state/clear-edit!)
-  (state/set-selection-blocks! blocks))
+  ([blocks]
+   (exit-editing-and-set-selected-blocks! blocks :down))
+  ([blocks direction]
+   (util/clear-selection!)
+   (state/clear-edit!)
+   (state/set-selection-blocks! blocks direction)
+   (util/select-highlight! blocks)))
 
 (defn select-all-blocks!
   []
@@ -808,8 +811,6 @@
     (let [input (gdom/getElement current-input-id)
           blocks-container (util/rec-get-blocks-container input)
           blocks (dom/by-class blocks-container "ls-block")]
-      (doseq [block blocks]
-        (dom/add-class! block "selected noselect"))
       (exit-editing-and-set-selected-blocks! blocks))))
 
 (defn- get-selected-blocks-with-children
@@ -827,10 +828,8 @@
           ids (->> (distinct (map #(when-let [id (dom/attr % "blockid")]
                                      (uuid id)) blocks))
                    (remove nil?))
-          up? (state/selection-up?)
           content (some->> (db/get-blocks-contents repo ids)
                            (map :block/content))
-          content (if (false? up?) (reverse content) content)
           content (string/join "" content)]
       (when-not (string/blank? content)
         (common-handler/copy-to-clipboard-without-id-property! content)))))
@@ -934,13 +933,11 @@
       (common-handler/copy-to-clipboard-without-id-property! content)
       (delete-block-aux! block false))))
 
-(defonce select-start-block-state (atom nil))
-
 (defn clear-last-selected-block!
   []
-  (let [first-block (state/pop-selection-block!)]
-    (dom/remove-class! first-block "selected")
-    (dom/remove-class! first-block "noselect")))
+  (let [block (state/drop-last-selection-block!)]
+    (dom/remove-class! block "selected")
+    (dom/remove-class! block "noselect")))
 
 (defn input-start-or-end?
   ([input]
@@ -958,46 +955,36 @@
   [end-block]
   (when-let [start-block (:selection/start-block @state/state)]
     (clear-selection! nil)
-    (let [blocks (util/get-nodes-between-two-nodes start-block end-block "ls-block")]
-      (doseq [block blocks]
-        (dom/add-class! block "selected noselect"))
+    (let [blocks (util/get-nodes-between-two-nodes start-block end-block "ls-block")
+
+          direction (util/get-direction-between-two-nodes start-block end-block "ls-block")]
       (exit-editing-and-set-selected-blocks! blocks))))
 
 (defn on-select-block
-  [state e up?]
-  (when (and
-         (gobj/get e "shiftKey")
-         (not (gobj/get e "altKey"))
-         (or (state/in-selection-mode?)
-             (when-let [input-id (state/get-edit-input-id)]
-               (when-let [input (gdom/getElement input-id)]
-                 (input-start-or-end? input up?)))))
-    (state/clear-edit!)
-    (let [{:keys [id block-id block block-parent-id dummy? value pos format] :as block-state} @select-start-block-state
-          element (gdom/getElement block-parent-id)
-          selected-blocks (state/get-selection-blocks)
-          selected-blocks-count (count selected-blocks)
-          first-block (first selected-blocks)
-          selection-up? (state/selection-up?)]
-      (when block-id
-        (util/stop e)
-        (when-let [element (if-not (state/in-selection-mode?)
-                             element
-                             (let [f (if up? util/get-prev-block util/get-next-block)]
-                               (f first-block)))]
-          (if (and (not (nil? selection-up?)) (not= up? selection-up?))
-            (cond
-              (>= selected-blocks-count 2) ; back to the start block
-              (do
-                (when (= 2 selected-blocks-count) (state/set-selection-up! nil))
-                (clear-last-selected-block!))
-
-              :else
-              nil)
-            (do
-              (util/clear-selection!)
-              (state/clear-edit!)
-              (state/conj-selection-block! element up?))))))))
+  [direction]
+  (fn [e]
+    (cond
+      ;; when editing, quit editing and select current block
+      (state/editing?)
+      (exit-editing-and-set-selected-blocks! [(gdom/getElement (state/get-editing-block-dom-id))])
+
+      ;; when selection and one block selected, select next block
+      (and (state/in-selection-mode?) (== 1 (count (state/get-selection-blocks))))
+      (let [f (if (= :up direction) util/get-prev-block util/get-next-block)
+            element (f (first (state/get-selection-blocks)))]
+        (when element
+          (state/conj-selection-block! element direction)))
+
+      ;; if same direction, keep conj on same direction
+      (and (state/in-selection-mode?) (= direction (state/get-selection-direction)))
+      (let [f (if (= :up direction) util/get-prev-block util/get-next-block)
+            element (f (last (state/get-selection-blocks)))]
+        (when element
+          (state/conj-selection-block! element direction)))
+
+      ;; if different direction, keep clear until one left
+      (state/in-selection-mode?)
+      (clear-last-selected-block!))))
 
 (defn save-block-aux!
   [block value format opts]

+ 20 - 19
src/main/frontend/state.cljs

@@ -93,6 +93,9 @@
     :selection/mode false
     :selection/blocks []
     :selection/start-block nil
+    ;; either :up or :down, defaults to down
+    ;; used to determine selection direction when two or more blocks are selected
+    :selection/direction :down
     :custom-context-menu/show? false
     :custom-context-menu/links nil
 
@@ -507,12 +510,14 @@
   (get @state :selection/start-block))
 
 (defn set-selection-blocks!
-  [blocks]
-  (when (seq blocks)
-    (swap! state assoc
-           :selection/mode true
-           :selection/blocks blocks)))
-
+  ([blocks]
+   (set-selection-blocks! blocks :down))
+  ([blocks direction]
+   (when (seq blocks)
+     (swap! state assoc
+            :selection/mode true
+            :selection/blocks blocks
+            :selection/direction direction))))
 (defn into-selection-mode!
   []
   (swap! state assoc :selection/mode true))
@@ -522,7 +527,7 @@
   (swap! state assoc
          :selection/mode false
          :selection/blocks nil
-         :selection/up? nil))
+         :selection/direction :down))
 
 (defn clear-selection-blocks!
   []
@@ -537,28 +542,24 @@
   (:selection/mode @state))
 
 (defn conj-selection-block!
-  [block up?]
+  [block direction]
   (dom/add-class! block "selected noselect")
   (swap! state assoc
          :selection/mode true
          :selection/blocks (conj (:selection/blocks @state) block)
-         :selection/up? up?))
+         :selection/direction direction))
 
-(defn pop-selection-block!
+(defn drop-last-selection-block!
   []
-  (let [[first-block & others] (:selection/blocks @state)]
+  (let [last-block (peek (:selection/blocks @state))]
     (swap! state assoc
            :selection/mode true
-           :selection/blocks others)
-    first-block))
+           :selection/blocks (vec (pop (:selection/blocks @state))))
+    last-block))
 
-(defn selection-up?
+(defn get-selection-direction
   []
-  (:selection/up? @state))
-
-(defn set-selection-up!
-  [value]
-  (swap! state assoc :selection/up? value))
+  (:selection/direction @state))
 
 (defn show-custom-context-menu!
   [links]