Browse Source

fix: code block editing issue

Tienson Qin 4 years ago
parent
commit
b130f88bfc

+ 45 - 52
src/main/frontend/extensions/code.cljs

@@ -106,58 +106,49 @@
 
 (defn render!
   [state]
-  (let [editor-atom (:editor-atom state)
-        esc-pressed? (atom nil)
+  (let [esc-pressed? (atom nil)
         dark? (state/dark?)]
-    (if @editor-atom
-      (let [editor @editor-atom
-            doc (.getDoc editor)
-            code (nth (:rum/args state) 3)]
-        (.setValue doc code)
-        @editor-atom)
-      (let [[config id attr code theme] (:rum/args state)
-            original-mode (get attr :data-lang)
-            mode original-mode
-            clojure? (contains? #{"clojure" "clj" "text/x-clojure" "cljs" "cljc"} mode)
-            mode (if clojure? "clojure" (text->cm-mode mode))
-            lisp? (or clojure?
-                      (contains? #{"scheme" "racket" "lisp"} mode))
-            textarea (gdom/getElement id)
-            editor (or
-                    @(:editor-atom state)
-                    (when textarea
-                      (from-textarea textarea
-                                     #js {:mode mode
-                                          :theme (str "solarized " theme)
-                                          :matchBrackets lisp?
-                                          :autoCloseBrackets true
-                                          :lineNumbers true
-                                          :styleActiveLine true
-                                          :extraKeys #js {"Esc" (fn [cm]
-                                                                  (save-file-or-block-when-blur-or-esc! cm textarea config state)
-                                                                  (when-let [block-id (:block/uuid config)]
-                                                                    (let [block (db/pull [:block/uuid block-id])
-                                                                          value (.getValue cm)
-                                                                          textarea-value (gobj/get textarea "value")]
-                                                                      (editor-handler/edit-block! block :max (:block/format block) block-id)))
-                                                                  ;; TODO: return "handled" or false doesn't always prevent event bubbles
-                                                                  (reset! esc-pressed? true)
-                                                                  (js/setTimeout #(reset! esc-pressed? false) 10))}})))]
-        (when editor
-          (let [element (.getWrapperElement editor)]
-            (.on editor "blur" (fn [_cm e]
-                                 (when e (util/stop e))
-                                 (state/set-block-component-editing-mode! false)
-                                 (when-not @esc-pressed?
-                                   (save-file-or-block-when-blur-or-esc! editor textarea config state))))
-            (.addEventListener element "mousedown"
-                               (fn [e]
-                                 (state/clear-selection!)
-                                 (util/stop e)
-                                 (state/set-block-component-editing-mode! true)))
-            (.save editor)
-            (.refresh editor)))
-        editor))))
+    (let [[config id attr code theme] (:rum/args state)
+          original-mode (get attr :data-lang)
+          mode original-mode
+          clojure? (contains? #{"clojure" "clj" "text/x-clojure" "cljs" "cljc"} mode)
+          mode (if clojure? "clojure" (text->cm-mode mode))
+          lisp? (or clojure?
+                    (contains? #{"scheme" "racket" "lisp"} mode))
+          textarea (gdom/getElement id)
+          editor (when textarea
+                   (from-textarea textarea
+                                  #js {:mode mode
+                                       :theme (str "solarized " theme)
+                                       :matchBrackets lisp?
+                                       :autoCloseBrackets true
+                                       :lineNumbers true
+                                       :styleActiveLine true
+                                       :extraKeys #js {"Esc" (fn [cm]
+                                                               (save-file-or-block-when-blur-or-esc! cm textarea config state)
+                                                               (when-let [block-id (:block/uuid config)]
+                                                                 (let [block (db/pull [:block/uuid block-id])
+                                                                       value (.getValue cm)
+                                                                       textarea-value (gobj/get textarea "value")]
+                                                                   (editor-handler/edit-block! block :max (:block/format block) block-id)))
+                                                               ;; TODO: return "handled" or false doesn't always prevent event bubbles
+                                                               (reset! esc-pressed? true)
+                                                               (js/setTimeout #(reset! esc-pressed? false) 10))}}))]
+      (when editor
+        (let [element (.getWrapperElement editor)]
+          (.on editor "blur" (fn [_cm e]
+                               (when e (util/stop e))
+                               (state/set-block-component-editing-mode! false)
+                               (when-not @esc-pressed?
+                                 (save-file-or-block-when-blur-or-esc! editor textarea config state))))
+          (.addEventListener element "mousedown"
+                             (fn [e]
+                               (state/clear-selection!)
+                               (util/stop e)
+                               (state/set-block-component-editing-mode! true)))
+          (.save editor)
+          (.refresh editor)))
+      editor)))
 
 (defn- load-and-render!
   [state]
@@ -173,7 +164,9 @@
                 state)
    :did-update (fn [state]
                  (when-let [editor @(:editor-atom state)]
-                   (.setOption editor "theme" (str "solarized " (nth (state :rum/args) 4))))
+                   ;; clear the previous instance
+                   (.toTextArea ^js editor))
+                 (load-and-render! state)
                  state)}
   [state config id attr code theme options]
   [:div.extensions__code

+ 1 - 14
src/main/frontend/format/block.cljs

@@ -372,19 +372,6 @@
                               [:block/name (string/lower-case tag)]) tags))
     block))
 
-(defn- remove-indentation-spaces
-  [s level]
-  (let [level (inc level)
-        lines (string/split-lines s)
-        [f & r] lines
-        body (map (fn [line]
-                    (if (string/blank? (util/safe-subs line 0 level))
-                      (util/safe-subs line level)
-                      line))
-                  r)
-        content (cons f body)]
-    (string/join "\n" content)))
-
 (defn src-block?
   [block]
   (some (fn [x] (and (vector? x) (= "Src" (first x)))) (:body block)))
@@ -404,7 +391,7 @@
                       (if (or (:pre-block? block)
                               (= (:format block) :org))
                         content
-                        (remove-indentation-spaces content (:level block)))))]
+                        (text/remove-indentation-spaces content (inc (:level block)) false))))]
       (if (= format :org)
         content
         (property/->new-properties content)))))

+ 6 - 3
src/main/frontend/format/mldoc.cljs

@@ -2,6 +2,7 @@
   (:require [frontend.format.protocol :as protocol]
             [frontend.util :as util]
             [frontend.utf8 :as utf8]
+            [frontend.text :as text]
             [clojure.string :as string]
             [cljs-bean.core :as bean]
             [cljs.core.match :refer-macros [match]]
@@ -198,9 +199,11 @@
           (if (and (vector? block)
                    (= "Src" (first block)))
             (let [{:keys [start_pos end_pos]} pos-meta
-                  block ["Src" (assoc (second block)
-                                      :full_content
-                                      (utf8/substring content start_pos end_pos))]]
+                  content (utf8/substring content start_pos end_pos)
+                  spaces (re-find #"^[\t ]+" (first (string/split-lines content)))
+                  content (if spaces (text/remove-indentation-spaces content (count spaces) true)
+                              content)
+                  block ["Src" (assoc (second block) :full_content content)]]
               [block pos-meta])
             [block pos-meta])) ast)))
 

+ 12 - 0
src/main/frontend/text.cljs

@@ -173,3 +173,15 @@
       (string/replace "- DOING -> DONE [" "* DOING -> DONE [")
       (string/replace "- LATER -> DONE [" "* LATER -> DONE [")
       (string/replace "- NOW -> DONE [" "* NOW -> DONE [")))
+
+(defn remove-indentation-spaces
+  [s level remove-first-line?]
+  (let [lines (string/split-lines s)
+        [f & r] lines
+        body (map (fn [line]
+                    (if (string/blank? (util/safe-subs line 0 level))
+                      (util/safe-subs line level)
+                      line))
+               (if remove-first-line? lines r))
+        content (if remove-first-line? body (cons f body))]
+    (string/join "\n" content)))