🐛 Fix problems with old texts

This commit is contained in:
alonso.torres 2022-02-24 14:04:43 +01:00
parent ec63d23666
commit 64ffa9bb3f
10 changed files with 107 additions and 77 deletions

View file

@ -224,7 +224,7 @@
:internal.shape.text.position-data/font-size :internal.shape.text.position-data/font-size
:internal.shape.text.position-data/font-style :internal.shape.text.position-data/font-style
:internal.shape.text.position-data/font-weight :internal.shape.text.position-data/font-weight
:internal.shape.text.position-data/rtl? :internal.shape.text.position-data/rtl
:internal.shape.text.position-data/text :internal.shape.text.position-data/text
:internal.shape.text.position-data/text-decoration :internal.shape.text.position-data/text-decoration
:internal.shape.text.position-data/text-transform] :internal.shape.text.position-data/text-transform]
@ -243,7 +243,7 @@
(s/def :internal.shape.text.position-data/font-size string?) (s/def :internal.shape.text.position-data/font-size string?)
(s/def :internal.shape.text.position-data/font-style string?) (s/def :internal.shape.text.position-data/font-style string?)
(s/def :internal.shape.text.position-data/font-weight string?) (s/def :internal.shape.text.position-data/font-weight string?)
(s/def :internal.shape.text.position-data/rtl? boolean?) (s/def :internal.shape.text.position-data/rtl boolean?)
(s/def :internal.shape.text.position-data/text string?) (s/def :internal.shape.text.position-data/text string?)
(s/def :internal.shape.text.position-data/text-decoration string?) (s/def :internal.shape.text.position-data/text-decoration string?)
(s/def :internal.shape.text.position-data/text-transform string?) (s/def :internal.shape.text.position-data/text-transform string?)

View file

@ -117,13 +117,31 @@
;; --- Helpers ;; --- Helpers
(defn to-new-fills
[data]
[(d/without-nils (select-keys data [:fill-color :fill-opacity :fill-color-gradient :fill-color-ref-id :fill-color-ref-file]))])
(defn- shape-current-values (defn- shape-current-values
[shape pred attrs] [shape pred attrs]
(let [root (:content shape) (let [root (:content shape)
nodes (->> (txt/node-seq pred root) nodes (->> (txt/node-seq pred root)
(map #(if (txt/is-text-node? %) (map (fn [node]
(merge txt/default-text-attrs %) (if (txt/is-text-node? node)
%)))] (let [fills
(cond
(or (some? (:fill-color node))
(some? (:fill-opacity node))
(some? (:fill-color-gradient node)))
(to-new-fills node)
(some? (:fills node))
(:fills node)
:else
(:fills txt/default-text-attrs))]
(-> (merge txt/default-text-attrs node)
(assoc :fills fills)))
node))))]
(attrs/get-attrs-multi nodes attrs))) (attrs/get-attrs-multi nodes attrs)))
(defn current-root-values (defn current-root-values
@ -140,8 +158,10 @@
(defn current-text-values (defn current-text-values
[{:keys [editor-state attrs shape]}] [{:keys [editor-state attrs shape]}]
(if editor-state (if editor-state
(-> (ted/get-editor-current-inline-styles editor-state) (let [result (-> (ted/get-editor-current-inline-styles editor-state)
(select-keys attrs)) (select-keys attrs))
result (if (empty? result) txt/default-text-attrs result)]
result)
(shape-current-values shape txt/is-text-node? attrs))) (shape-current-values shape txt/is-text-node? attrs)))
@ -220,24 +240,27 @@
(cph/group-shape? shape) (cph/get-children-ids objects id))] (cph/group-shape? shape) (cph/get-children-ids objects id))]
(rx/of (dch/update-shapes shape-ids #(update-text-content % update-node? attrs/merge attrs)))))))) (rx/of (dch/update-shapes shape-ids #(update-text-content % update-node? attrs/merge attrs))))))))
(defn migrate-node
[node]
(let [color-attrs (select-keys node [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient])]
(cond-> node
(d/not-empty? color-attrs)
(-> (dissoc :fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient)
(assoc :fills [color-attrs]))
(nil? (:fills node))
(assoc :fills (:fills txt/default-text-attrs)))))
(defn migrate-content (defn migrate-content
[content] [content]
(txt/transform-nodes (txt/transform-nodes (some-fn txt/is-text-node? txt/is-paragraph-node?) migrate-node content))
#(or (txt/is-text-node? %) (txt/is-paragraph-node? %))
(fn [node]
(let [color-attrs (select-keys node [:fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient])]
(cond-> node
(d/not-empty? color-attrs)
(-> (dissoc :fill-color :fill-opacity :fill-color-ref-id :fill-color-ref-file :fill-color-gradient)
(assoc :fills [color-attrs])))))
content))
(defn update-text-with-function (defn update-text-with-function
[id update-node-fn] [id update-node-fn]
(ptk/reify ::update-text-with-function (ptk/reify ::update-text-with-function
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(d/update-in-when state [:workspace-editor-state id] ted/update-editor-current-inline-styles-fn update-node-fn)) (d/update-in-when state [:workspace-editor-state id] ted/update-editor-current-inline-styles-fn (comp update-node-fn migrate-node)))
ptk/WatchEvent ptk/WatchEvent
(watch [_ state _] (watch [_ state _]
@ -245,10 +268,7 @@
(let [objects (wsh/lookup-page-objects state) (let [objects (wsh/lookup-page-objects state)
shape (get objects id) shape (get objects id)
update-node? update-node? (some-fn txt/is-text-node? txt/is-paragraph-node?)
(fn [node]
(or (txt/is-text-node? node)
(txt/is-paragraph-node? node)))
shape-ids shape-ids
(cond (cond

View file

@ -48,11 +48,10 @@
(mf/set-ref-val! prev-obs-ref mutation-obs) (mf/set-ref-val! prev-obs-ref mutation-obs)
(.observe mutation-obs node options))))))] (.observe mutation-obs node options))))))]
(mf/use-effect (mf/with-effect
(fn [] (fn []
(fn [] (when-let [^js prev-obs (mf/ref-val prev-obs-ref)]
(when-let [^js prev-obs (mf/ref-val prev-obs-ref)] (.disconnect prev-obs)
(.disconnect prev-obs) (mf/set-ref-val! prev-obs-ref nil))))
(mf/set-ref-val! prev-obs-ref nil)))))
[node-ref set-node])) [node-ref set-node]))

View file

@ -6,6 +6,7 @@
(ns app.main.ui.render (ns app.main.ui.render
(:require (:require
[app.common.data :as d]
[app.common.geom.matrix :as gmt] [app.common.geom.matrix :as gmt]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
@ -92,12 +93,11 @@
(mf/with-memo [objects] (mf/with-memo [objects]
(render/shape-wrapper-factory objects)) (render/shape-wrapper-factory objects))
text-shapes is-text? (fn [shape] (= :text (:type shape)))
(->> objects
(filter (fn [[_ shape]] (= :text (:type shape))))
(mapv second))
render-texts? (and render-texts? (some #(nil? (:position-data %)) text-shapes))] text-shapes (sequence (comp (map second) (filter is-text?)) objects)
render-texts? (and render-texts? (d/seek (comp nil? :position-data) text-shapes))]
(mf/with-effect [width height] (mf/with-effect [width height]
(dom/set-page-style {:size (str (mth/ceil width) "px " (dom/set-page-style {:size (str (mth/ceil width) "px "

View file

@ -89,11 +89,11 @@
(cond (cond
(contains? shape :fill-image) (contains? shape :fill-image)
(let [fill-image-id (str "fill-image-" render-id)] (let [fill-image-id (str "fill-image-" render-id)]
{:fill (str/format "url(#%s)" fill-image-id)}) {:fill (str "url(#" fill-image-id ")")})
(contains? shape :fill-color-gradient) (contains? shape :fill-color-gradient)
(let [fill-color-gradient-id (str "fill-color-gradient_" render-id (if index (str "_" index) ""))] (let [fill-color-gradient-id (str "fill-color-gradient_" render-id (if index (str "_" index) ""))]
{:fill (str/format "url(#%s)" fill-color-gradient-id)}) {:fill (str "url(#" fill-color-gradient-id ")")})
(contains? shape :fill-color) (contains? shape :fill-color)
{:fill (:fill-color shape)} {:fill (:fill-color shape)}

View file

@ -45,19 +45,18 @@
(= :path (:type shape)) (= :path (:type shape))
(obj/set! "patternTransform" transform))] (obj/set! "patternTransform" transform))]
[:* (for [[shape-index shape] (d/enumerate (or (:position-data shape) [shape]))]
(for [[_shape-index shape] (d/enumerate (or (:position-data shape) [shape]))] [:*
(for [[fill-index value] (-> (d/enumerate (:fills shape [])) reverse)] (for [[fill-index value] (-> (d/enumerate (:fills shape [])) reverse)]
(cond (some? (:fill-color-gradient value)) (when (some? (:fill-color-gradient value))
(case (d/name (:type (:fill-color-gradient value))) (let [props #js {:id (str "fill-color-gradient_" render-id "_" fill-index)
"linear" [:> grad/linear-gradient #js {:id (str "fill-color-gradient_" render-id "_" fill-index) :gradient (:fill-color-gradient value)
:gradient (:fill-color-gradient value) :shape shape}]
:shape shape}] (case (d/name (:type (:fill-color-gradient value)))
"radial" [:> grad/radial-gradient #js {:id (str "fill-color-gradient_" render-id "_" fill-index) "linear" [:> grad/linear-gradient props]
:gradient (:fill-color-gradient value) "radial" [:> grad/radial-gradient props]))))
:shape shape}]))))
(for [[shape-index shape] (d/enumerate (or (:position-data shape) [shape]))]
(let [fill-id (str "fill-" shape-index "-" render-id)] (let [fill-id (str "fill-" shape-index "-" render-id)]
[:> :pattern (-> (obj/clone pattern-attrs) [:> :pattern (-> (obj/clone pattern-attrs)
(obj/set! "id" fill-id)) (obj/set! "id" fill-id))
@ -70,4 +69,4 @@
(when has-image (when has-image
[:image {:xlinkHref (get embed uri uri) [:image {:xlinkHref (get embed uri uri)
:width width :width width
:height height}])]]))])))) :height height}])]])])))))

View file

@ -87,11 +87,22 @@
:caretColor (or text-color "black") :caretColor (or text-color "black")
:overflowWrap "initial"} :overflowWrap "initial"}
base (-> base fills
(obj/set! "--fills" (transit/encode-str (:fills data))) (cond
#_(obj/set! "--fill-color" fill-color) (some? (:fills data))
#_(obj/set! "--fill-color-gradient" (transit/encode-str (:fill-color-gradient data))) (:fills data)
#_(obj/set! "--fill-opacity" fill-opacity))]
(or (some? (:fill-color data))
(some? (:fill-opacity data))
(some? (:fill-color-gradient data)))
[(d/without-nils (select-keys data [:fill-color :fill-opacity :fill-color-gradient :fill-color-ref-id :fill-color-ref-file]))]
(nil? (:fills data))
[{:fill-color "#000000" :fill-opacity 1}])
base (cond-> base
(some? fills)
(obj/set! "--fills" (transit/encode-str fills)))]
(when (and (string? letter-spacing) (when (and (string? letter-spacing)
(pos? (alength letter-spacing))) (pos? (alength letter-spacing)))

View file

@ -57,10 +57,9 @@
:textTransform (:text-transform data) :textTransform (:text-transform data)
:textDecoration (:text-decoration data) :textDecoration (:text-decoration data)
:fontStyle (:font-style data) :fontStyle (:font-style data)
:direction (if (:rtl? data) "rtl" "ltr") :direction (if (:rtl data) "rtl" "ltr")
:whiteSpace "pre"} :whiteSpace "pre"}
(obj/set! "fill" (str "url(#fill-" index "-" render-id ")")) (obj/set! "fill" (str "url(#fill-" index "-" render-id ")")))})]
#_(attrs/add-fill data (get-gradient-id index)))})]
[:& shape-custom-stroke {:shape shape :index index} [:& shape-custom-stroke {:shape shape :index index}
[:> :text props (:text data)]]))]])) [:> :text props (:text data)]]))]]))

View file

@ -131,25 +131,26 @@
sid-ref (mf/use-ref nil) sid-ref (mf/use-ref nil)
handle-change-foreign-object handle-change-foreign-object
(fn [node] (mf/use-callback
(when-let [position-data (utp/calc-position-data node)] (fn [node]
(let [parent (dom/get-parent node) (when-let [position-data (utp/calc-position-data node)]
parent-transform (dom/get-attribute parent "transform") (let [parent (dom/get-parent node)
node-transform (dom/get-attribute node "transform") parent-transform (dom/get-attribute parent "transform")
node-transform (dom/get-attribute node "transform")
parent-mtx (usvg/parse-transform parent-transform) parent-mtx (usvg/parse-transform parent-transform)
node-mtx (usvg/parse-transform node-transform) node-mtx (usvg/parse-transform node-transform)
;; We need to see what transformation is applied in the DOM to reverse it ;; We need to see what transformation is applied in the DOM to reverse it
;; before calculating the position data ;; before calculating the position data
mtx (-> (gmt/multiply parent-mtx node-mtx) mtx (-> (gmt/multiply parent-mtx node-mtx)
(gmt/inverse)) (gmt/inverse))
position-data position-data
(->> position-data (->> position-data
(mapv #(merge % (-> (select-keys % [:x :y :width :height]) (mapv #(merge % (-> (select-keys % [:x :y :width :height])
(gsh/transform-rect mtx)))))] (gsh/transform-rect mtx)))))]
(reset! local-position-data position-data)))) (reset! local-position-data position-data)))))
[node-ref on-change-node] (use-mutable-observer handle-change-foreign-object) [node-ref on-change-node] (use-mutable-observer handle-change-foreign-object)

View file

@ -22,9 +22,10 @@
(.setEnd range node end-i) (.setEnd range node end-i)
(.getClientRects range))) (.getClientRects range)))
;; TODO: Evaluate to change this function to Javascript
(defn parse-text-nodes (defn parse-text-nodes
"Given a text node retrieves the rectangles for everyone of its paragraphs and its text." "Given a text node retrieves the rectangles for everyone of its paragraphs and its text."
[parent-node rtl? text-node] [parent-node rtl text-node]
(let [content (.-textContent text-node) (let [content (.-textContent text-node)
text-size (.-length content)] text-size (.-length content)]
@ -45,7 +46,7 @@
;; If the rects increase means we're in a new paragraph ;; If the rects increase means we're in a new paragraph
(if (> (.-length rects) 1) (if (> (.-length rects) 1)
(let [entry {:node parent-node (let [entry {:node parent-node
:position (dom/bounding-rect->rect (if rtl? (second rects) (first rects))) :position (dom/bounding-rect->rect (if rtl (second rects) (first rects)))
:text current}] :text current}]
(recur to-i to-i "" (conj result entry))) (recur to-i to-i "" (conj result entry)))
(recur from-i (inc to-i) (str current (nth content to-i)) result))))))) (recur from-i (inc to-i) (str current (nth content to-i)) result)))))))
@ -86,9 +87,9 @@
(->> text-nodes (->> text-nodes
(mapcat (mapcat
(fn [parent-node] (fn [parent-node]
(let [rtl? (= "rtl" (.-dir (.-parentElement parent-node)))] (let [rtl (= "rtl" (.-dir (.-parentElement parent-node)))]
(->> (.-childNodes parent-node) (->> (.-childNodes parent-node)
(mapcat #(parse-text-nodes parent-node rtl? %)))))) (mapcat #(parse-text-nodes parent-node rtl %))))))
(mapv #(update % :position translate-rect)))))) (mapv #(update % :position translate-rect))))))
(defn calc-position-data (defn calc-position-data
@ -101,15 +102,15 @@
(->> text-data (->> text-data
(mapv (fn [{:keys [node position text]}] (mapv (fn [{:keys [node position text]}]
(let [{:keys [x y width height]} position (let [{:keys [x y width height]} position
rtl? (= "rtl" (.-dir (.-parentElement ^js node))) rtl (= "rtl" (.-dir (.-parentElement ^js node)))
styles (js/getComputedStyle ^js node) styles (js/getComputedStyle ^js node)
get (fn [prop] get (fn [prop]
(let [value (.getPropertyValue styles prop)] (let [value (.getPropertyValue styles prop)]
(when (and value (not= value "")) (when (and value (not= value ""))
value)))] value)))]
(d/without-nils (d/without-nils
{:rtl? rtl? {:rtl rtl
:x (if rtl? (+ x width) x) :x (if rtl (+ x width) x)
:y (+ y height) :y (+ y height)
:width width :width width
:height height :height height