Browse Source

enhance: warning on invalid properties

Tienson Qin 3 years ago
parent
commit
abc33f213c

+ 4 - 0
deps/db/src/logseq/db/schema.cljs

@@ -116,6 +116,8 @@
     :block/heading-level
     :block/type
     :block/properties
+    :block/properties-order
+    :block/invalid-properties
     :block/created-at
     :block/updated-at
     :block/warning
@@ -132,5 +134,7 @@
     :block/format
     :block/content
     :block/properties
+    :block/properties-order
+    :block/invalid-properties
     :block/alias
     :block/tags})

+ 15 - 11
deps/graph-parser/src/logseq/graph_parser/block.cljs

@@ -199,22 +199,19 @@
          (remove string/blank?)
          distinct)))
 
-(defn- invalid-property-key?
-  [s]
-  (string/includes? s "`"))
-
 (defn extract-properties
   [format properties user-config]
   (when (seq properties)
     (let [properties (seq properties)
           page-refs (get-page-ref-names-from-properties format properties user-config)
+          *invalid-properties (atom #{})
           properties (->> properties
                           (map (fn [[k v]]
                                  (let [k (-> (string/lower-case (name k))
                                              (string/replace " " "-")
                                              (string/replace "_" "-")
                                              (string/replace #"[\"|^|(|)|{|}]+" ""))]
-                                   (when-not (invalid-property-key? k)
+                                   (if (gp-util/valid-edn-keyword? (str ":" k))
                                      (let [k (if (contains? #{"custom_id" "custom-id"} k)
                                                "id"
                                                k)
@@ -235,10 +232,13 @@
                                                (set [v])
                                                v)
                                            v (if (coll? v) (set v) v)]
-                                       [k v])))))
-                          (remove #(nil? (second %))))]
-      {:properties (into {} properties)
-       :properties-order (map first properties)
+                                       [k v])
+                                     (swap! *invalid-properties conj k)))))
+                          (remove #(nil? (second %))))
+          properties' (into {} properties)]
+      {:properties properties'
+       :properties-order (map first properties')
+       :invalid-properties @*invalid-properties
        :page-refs page-refs})))
 
 (defn- paragraph-timestamp-block?
@@ -533,7 +533,7 @@
                  (cons
                   (merge
                    (let [content (utf8/substring encoded-content 0 first-block-start-pos)
-                         {:keys [properties properties-order]} pre-block-properties
+                         {:keys [properties properties-order invalid-properties]} pre-block-properties
                          id (get-custom-id-or-new-id {:properties properties})
                          property-refs (->> (get-page-refs-from-properties format properties db date-formatter user-config)
                                             (map :block/original-name))
@@ -542,6 +542,7 @@
                                 :level 1
                                 :properties properties
                                 :properties-order (vec properties-order)
+                                :invalid-properties invalid-properties
                                 :refs property-refs
                                 :pre-block? true
                                 :unordered true
@@ -578,7 +579,10 @@
                 (assoc :properties (:properties properties))
 
                 (seq (:properties-order properties))
-                (assoc :properties-order (vec (:properties-order properties))))
+                (assoc :properties-order (vec (:properties-order properties)))
+
+                (seq (:invalid-properties properties))
+                (assoc :invalid-properties (:invalid-properties properties)))
         block (if (get-in block [:properties :collapsed])
                 (-> (assoc block :collapsed? true)
                     (update :properties (fn [m] (dissoc m :collapsed)))

+ 12 - 1
deps/graph-parser/src/logseq/graph_parser/util.cljs

@@ -2,7 +2,8 @@
   "Util fns shared between graph-parser and rest of app. Util fns only rely on
   clojure standard libraries."
   (:require [clojure.walk :as walk]
-            [clojure.string :as string]))
+            [clojure.string :as string]
+            [clojure.edn :as edn]))
 
 (defn path-normalize
   "Normalize file path (for reading paths from FS, not required by writting)"
@@ -147,3 +148,13 @@
   [file]
   (when file
     (normalize-format (keyword (string/lower-case (last (string/split file #"\.")))))))
+
+(defn valid-edn-keyword?
+  [k]
+  (try
+    (let [s (str k)]
+      (and (= \: (first s))
+           (edn/read-string (str "{" s " nil}"))))
+    true
+    (catch :default _
+      false)))

+ 13 - 0
src/main/frontend/components/block.cljs

@@ -1903,6 +1903,16 @@
       :else
       nil)))
 
+(rum/defc invalid-properties-cp
+  [invalid-properties]
+  (when (seq invalid-properties)
+    [:div.invalid-properties.mb-2
+     [:div.warning {:title "Invalid properties"}
+      "Invalid property keys: "
+      (for [p invalid-properties]
+        [:button.p-1.mr-2 p])]
+     [:code "Property key begins with a non-numeric character and can contain alphanumeric characters and . * + ! - _ ? $ % & = < >. If -, + or . are the first character, the second character (if any) must be non-numeric."]]))
+
 (rum/defcs timestamp-cp < rum/reactive
   (rum/local false ::show?)
   (rum/local {} ::pos)
@@ -2109,6 +2119,9 @@
         (when-let [scheduled-ast (block-handler/get-scheduled-ast block)]
           (timestamp-cp block "SCHEDULED" scheduled-ast)))
 
+      (when-let [invalid-properties (:block/invalid-properties block)]
+        (invalid-properties-cp invalid-properties))
+
       (when (and (seq properties)
                  (let [hidden? (property/properties-hidden? properties)]
                    (not hidden?))

+ 7 - 17
src/main/frontend/handler/export.cljs

@@ -26,8 +26,7 @@
             [logseq.graph-parser.util.block-ref :as block-ref]
             [logseq.graph-parser.util.page-ref :as page-ref]
             [promesa.core :as p]
-            [frontend.handler.notification :as notification]
-            [clojure.edn :as edn])
+            [frontend.handler.notification :as notification])
   (:import
    [goog.string StringBuffer]))
 
@@ -445,23 +444,14 @@
        x))
    vec-tree))
 
-(defn- valid-edn-keyword?
-  [k]
-  (try
-    (edn/read-string (str k))
-    true
-    (catch :default _
-      false)))
-
-(defn- non-safe-keyword->str
+(defn- safe-keywordize
   [block]
   (update block :block/properties
           (fn [properties]
             (when (seq properties)
-              (update-keys properties (fn [k]
-                                        (if (valid-edn-keyword? k)
-                                          (subs (str k) 1)
-                                          k)))))))
+              (->> (filter (fn [[k v]]
+                             (gp-util/valid-edn-keyword? k)) properties)
+                   (into {}))))))
 
 (defn- blocks [db]
   {:version 1
@@ -483,9 +473,9 @@
                                                (update b :block/content
                                                        (fn [content] (property/remove-properties (:block/format b) content)))
                                                b)]
-                                      (non-safe-keyword->str b'))) blocks)
+                                      (safe-keywordize b'))) blocks)
                      children (outliner-tree/blocks->vec-tree blocks' name)
-                     page' (non-safe-keyword->str page)]
+                     page' (safe-keywordize page)]
                  (assoc page' :block/children children))))
         (nested-select-keys
          [:block/id