Browse Source

fix(editor): unstable properties when updating or creating a block

Resolved #1017
Tienson Qin 5 years ago
parent
commit
2555cc9121

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

@@ -111,8 +111,9 @@
           properties (cond-> properties
                        (seq macros)
                        (assoc :macros macros))
-          properties (-> properties
-                         (update :alias (fn [alias] (if (string? alias) [alias] alias))))
+          properties (if (:alias properties)
+                       (update properties :alias (fn [alias] (if (string? alias) [alias] alias)))
+                       properties)
           other-ast (drop-while (fn [[item _pos]] (directive? item)) original-ast)]
       (if (seq properties)
         (cons [["Properties" properties] nil] other-ast)

+ 9 - 7
src/main/frontend/handler/editor.cljs

@@ -410,7 +410,7 @@
   [block format value]
   (let [value (text/remove-level-spaces value (keyword format))
         properties (with-time-properties block {})]
-    (text/re-construct-block-properties value properties)))
+    (text/re-construct-block-properties format value properties)))
 
 (defn save-block-if-changed!
   ([block value]
@@ -421,7 +421,8 @@
      :or {rebuild-content? true
           custom-properties nil
           remove-properties nil
-          auto-save? false}}]
+          auto-save? false}
+     :as opts}]
    (let [value value
          repo (or repo (state/get-current-repo))
          e (db/entity repo [:block/uuid uuid])
@@ -442,7 +443,7 @@
                         (map
                          (fn [alias]
                            {:page/name (string/lower-case alias)})
-                          (remove #{(:page/name page)} alias))))
+                         (remove #{(:page/name page)} alias))))
          permalink-changed? (when (and pre-block? (:permalink old-properties))
                               (not= (:permalink old-properties)
                                     (:permalink new-properties)))
@@ -459,7 +460,7 @@
          properties (if (and (seq properties) (seq remove-properties))
                       (medley/remove-keys (fn [k] (contains? (set remove-properties) k)) properties)
                       properties)
-         value (text/re-construct-block-properties value properties)
+         value (text/re-construct-block-properties format value properties)
          content-changed? (not= (text/remove-timestamp-property! (string/trim content))
                                 (text/remove-timestamp-property! (string/trim value)))]
      (cond
@@ -525,7 +526,8 @@
                                                             (block/parse-block block format))
                  block-retracted-attrs (when-not pre-block?
                                          (when-let [id (:db/id block)]
-                                           [[:db/retract id :block/priority]
+                                           [[:db/retract id :block/properties]
+                                            [:db/retract id :block/priority]
                                             [:db/retract id :block/deadline]
                                             [:db/retract id :block/deadline-ast]
                                             [:db/retract id :block/scheduled]
@@ -646,7 +648,7 @@
                                      value)
                              text-properties (text/extract-properties fst-block-text)
                              properties (with-time-properties block text-properties)
-                             value (text/re-construct-block-properties value properties)
+                             value (text/re-construct-block-properties format value properties)
                              value (rebuild-block-content value format)
                              [new-content value] (new-file-content block file-content value)
                              parse-result (block/parse-block (assoc block :block/content value) format)
@@ -690,7 +692,7 @@
                                                         (util/uuid-string? blocks-container-id)
                                                         (medley/uuid blocks-container-id))]
 
-                           ; WORKAROUND: The block won't refresh itself even if the content is empty.
+                                        ; WORKAROUND: The block won't refresh itself even if the content is empty.
                            (when edit-self?
                              (gobj/set input "value" ""))
 

+ 24 - 10
src/main/frontend/text.cljs

@@ -36,13 +36,22 @@
 (defn split-page-refs-without-brackets
   [s]
   (if (and (string? s)
-             (or (re-find #"[\"|\,|,]+" s)
-                 (re-find page-ref-re s)))
-      (->> s
-        (sep-by-comma-or-quote)
-        (map page-ref-un-brackets!)
-        (set))
-      s))
+           (or (re-find #"[\"|\,|,]+" s)
+               (re-find page-ref-re s)))
+    (->> s
+         (sep-by-comma-or-quote)
+         (map page-ref-un-brackets!)
+         (set))
+    s))
+
+(defn extract-level-spaces
+  [text format]
+  (if-not (string/blank? text)
+    (let [pattern (util/format
+                   "^[%s]+\\s+"
+                   (config/get-block-pattern format))]
+      (re-find (re-pattern pattern) text))
+    ""))
 
 (defn remove-level-spaces
   ([text format]
@@ -175,9 +184,14 @@
          (into {}))))
 
 (defn re-construct-block-properties
-  [content properties]
-  (-> (remove-properties! content)
-      (rejoin-properties properties)))
+  [format content properties]
+  (let [format (keyword format)
+        level-spaces (extract-level-spaces content format)
+        result (-> content
+                   (remove-level-spaces format true)
+                   (remove-properties!)
+                   (rejoin-properties properties))]
+    (str level-spaces (string/triml result))))
 
 (defn insert-property
   [content key value]

+ 31 - 0
src/test/frontend/text_test.cljs

@@ -0,0 +1,31 @@
+(ns frontend.text-test
+  (:require [frontend.text :as text]
+            [cljs.test :refer [deftest is are testing use-fixtures]]))
+
+(deftest re-construct-block-properties
+  []
+  (testing "block content without a title"
+    (are [x y] (= x y)
+      (text/re-construct-block-properties :org "** :PROPERTIES:\n:x: y\n:END:\n" {"x" "y"})
+      "** :PROPERTIES:\n:x: y\n:END:\n"
+
+      (text/re-construct-block-properties :markdown "## :PROPERTIES:\n:x: y\n:END:\n" {"x" "y"})
+      "## :PROPERTIES:\n:x: y\n:END:\n"))
+
+  (testing "block content with a title"
+    (are [x y] (= x y)
+      (text/re-construct-block-properties :org "** hello\n:PROPERTIES:\n:x: y\n:END:\n" {"x" "y"})
+      "** hello\n:PROPERTIES:\n:x: y\n:END:\n"
+
+      (text/re-construct-block-properties :markdown "## hello\n:PROPERTIES:\n:x: y\n:END:\n" {"x" "y"})
+      "## hello\n:PROPERTIES:\n:x: y\n:END:\n"))
+
+  (testing "block content with custom properties"
+    (are [x y] (= x y)
+      (text/re-construct-block-properties :org "** hello\n:PROPERTIES:\n:x: y\n:END:\n" {"x" "z"})
+      "** hello\n:PROPERTIES:\n:x: z\n:END:\n"
+
+      (text/re-construct-block-properties :markdown "## hello\n:PROPERTIES:\n:x: y\n:END:\n" {"x" "y" "a" "b"})
+      "## hello\n:PROPERTIES:\n:x: y\n:a: b\n:END:\n")))
+
+#_(cljs.test/test-ns 'frontend.text-test)