diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index d262d04410..656e6e3a06 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -1429,7 +1429,7 @@ (def ^:private valid-stroke? (sm/lazy-validator cts/schema:stroke)) -(defmethod migrate-data "0007-clear-invalid-strokes-and-fills" +(defmethod migrate-data "0007-clear-invalid-strokes-and-fills-v2" [data _] (letfn [(clear-color-image [image] (select-keys image types.color/image-attrs)) @@ -1474,13 +1474,18 @@ (d/update-when :strokes fix-strokes) (d/update-when :fills fix-fills))) + (fix-text-content [content] + (->> content + (txt/transform-nodes txt/is-content-node? fix-object) + (txt/transform-nodes txt/is-paragraph-set-node? #(dissoc % :fills)))) + (update-shape [object] (-> object (fix-object) ;; The text shape also can has strokes and fils on the ;; text fragments so we need to fix them there (cond-> (cfh/text-shape? object) - (update :content (partial txt/transform-nodes identity fix-object))))) + (update :content fix-text-content)))) (update-container [container] (d/update-when container :objects d/update-vals update-shape))] @@ -1561,5 +1566,5 @@ "0004-clean-shadow-and-colors" "0005-deprecate-image-type" "0006-fix-old-texts-fills" - "0007-clear-invalid-strokes-and-fills" + "0007-clear-invalid-strokes-and-fills-v2" "0008-fix-library-colors-opacity"])) diff --git a/common/src/app/common/text.cljc b/common/src/app/common/text.cljc index 0c72896f98..84cc27b218 100644 --- a/common/src/app/common/text.cljc +++ b/common/src/app/common/text.cljc @@ -133,6 +133,10 @@ (and (string? (:text node)) (not= (:text node) ""))) +(defn is-paragraph-set-node? + [node] + (= "paragraph-set" (:type node))) + (defn is-paragraph-node? [node] (= "paragraph" (:type node))) @@ -143,7 +147,17 @@ (defn is-node? [node] - (or (is-text-node? node) (is-paragraph-node? node) (is-root-node? node))) + (or ^boolean (is-text-node? node) + ^boolean (is-paragraph-node? node) + ^boolean (is-paragraph-set-node? node) + ^boolean (is-root-node? node))) + +(defn is-content-node? + "Only matches content nodes, ignoring the paragraph-set nodes." + [node] + (or ^boolean (is-text-node? node) + ^boolean (is-paragraph-node? node) + ^boolean (is-root-node? node))) (defn transform-nodes ([transform root] diff --git a/frontend/src/app/main/data/workspace/colors.cljs b/frontend/src/app/main/data/workspace/colors.cljs index b78f2c4072..0803595c6f 100644 --- a/frontend/src/app/main/data/workspace/colors.cljs +++ b/frontend/src/app/main/data/workspace/colors.cljs @@ -12,7 +12,7 @@ [app.common.files.helpers :as cfh] [app.common.schema :as sm] [app.common.text :as txt] - [app.common.types.color :as ctc] + [app.common.types.color :as types.color] [app.common.types.fill :as types.fill] [app.common.types.shape :as shp] [app.common.types.shape.shadow :refer [check-shadow]] @@ -181,15 +181,19 @@ ([ids color position] (change-fill ids color position nil)) ([ids color position options] - (ptk/reify ::change-fill - ptk/WatchEvent - (watch [_ state _] - (let [change-fn #(assoc-shape-fill %1 position %2) - undo-id (js/Symbol)] - (rx/concat - (rx/of (dwu/start-undo-transaction undo-id)) - (transform-fill state ids color change-fn options) - (rx/of (dwu/commit-undo-transaction undo-id)))))))) + (assert (every? uuid? ids) "expect a coll of uuids for `ids`") + (assert (number? position) "expect a number for position") + + (let [color (types.color/check-color color)] + (ptk/reify ::change-fill + ptk/WatchEvent + (watch [_ state _] + (let [change-fn #(assoc-shape-fill %1 position %2) + undo-id (js/Symbol)] + (rx/concat + (rx/of (dwu/start-undo-transaction undo-id)) + (transform-fill state ids color change-fn options) + (rx/of (dwu/commit-undo-transaction undo-id))))))))) (defn change-fill-and-clear ([ids color] (change-fill-and-clear ids color nil)) @@ -208,33 +212,27 @@ ([ids color] (add-fill ids color nil)) ([ids color options] - (assert - (ctc/check-color color) - "expected a valid color struct") - - (assert - (every? uuid? ids) - "expected a valid coll of uuid's") - - (ptk/reify ::add-fill - ptk/WatchEvent - (watch [_ state _] - (let [change-fn - (fn [shape attrs] - (-> shape - (update :fills #(into [attrs] %)))) - undo-id - (js/Symbol)] - (rx/concat - (rx/of (dwu/start-undo-transaction undo-id)) - (transform-fill state ids color change-fn options) - (rx/of (dwu/commit-undo-transaction undo-id)))))))) + (assert (every? uuid? ids) "expected a valid coll of uuid's") + (let [color (types.color/check-color color)] + (ptk/reify ::add-fill + ptk/WatchEvent + (watch [_ state _] + (let [change-fn + (fn [shape attrs] + (-> shape + (update :fills #(into [attrs] %)))) + undo-id + (js/Symbol)] + (rx/concat + (rx/of (dwu/start-undo-transaction undo-id)) + (transform-fill state ids color change-fn options) + (rx/of (dwu/commit-undo-transaction undo-id))))))))) (defn remove-fill ([ids color position] (remove-fill ids color position nil)) ([ids color position options] - (assert (ctc/check-color color) + (assert (types.color/check-color color) "expected a valid color struct") (assert (every? uuid? ids) "expected a valid coll of uuid's") @@ -263,7 +261,7 @@ ([ids color] (remove-all-fills ids color nil)) ([ids color options] - (assert (ctc/check-color color) "expected a valid color struct") + (assert (types.color/check-color color) "expected a valid color struct") (assert (every? uuid? ids) "expected a valid coll of uuid's") @@ -573,11 +571,11 @@ "expected valid color operations") (assert - (ctc/check-color new-color) + (types.color/check-color new-color) "expected valid color structure") (assert - (ctc/check-color old-color) + (types.color/check-color old-color) "expected valid color structure") (ptk/reify ::change-color-in-selected @@ -599,7 +597,7 @@ (defn apply-color-from-palette [color stroke?] - (let [color (ctc/check-color color)] + (let [color (types.color/check-color color)] (ptk/reify ::apply-color-from-palette ptk/WatchEvent (watch [_ state _] @@ -634,7 +632,7 @@ (defn apply-color-from-colorpicker [color] - (let [color (ctc/check-color color)] + (let [color (types.color/check-color color)] (ptk/reify ::apply-color-from-colorpicker ptk/UpdateEvent (update [_ state] @@ -675,7 +673,7 @@ (defn add-recent-color [color] - (let [color (ctc/check-color color)] + (let [color (types.color/check-color color)] (ptk/reify ::add-recent-color ptk/UpdateEvent (update [_ state] @@ -695,11 +693,11 @@ (defn apply-color-from-assets [file-id color stroke?] - (let [color (ctc/check-library-color color)] + (let [color (types.color/check-library-color color)] (ptk/reify ::apply-color-from-asserts ptk/WatchEvent (watch [_ _ _] - (let [color (ctc/library-color->color color file-id)] + (let [color (types.color/library-color->color color file-id)] (rx/of (apply-color-from-palette color stroke?) (add-recent-color color))))))) @@ -722,7 +720,8 @@ [{:keys [hex alpha] :as data}] (-> data (assoc :color hex) - (assoc :opacity alpha))) + (assoc :opacity alpha) + (d/without-nils))) (defn clear-color-components [data] @@ -750,13 +749,14 @@ (clear-image-components current-color) :else - {:opacity opacity - :gradient (-> gradient - (assoc :type (case type - :linear-gradient :linear - :radial-gradient :radial)) - (assoc :stops (mapv clear-color-components stops)) - (dissoc :shape-id))})) + (d/without-nils + {:opacity opacity + :gradient (-> gradient + (assoc :type (case type + :linear-gradient :linear + :radial-gradient :radial)) + (assoc :stops (mapv clear-color-components stops)) + (dissoc :shape-id))}))) (defn- colorpicker-onchange-runner "Effect event that runs the on-change callback with the latest diff --git a/frontend/test/frontend_tests/data/workspace_colors_test.cljs b/frontend/test/frontend_tests/data/workspace_colors_test.cljs new file mode 100644 index 0000000000..947bb6e820 --- /dev/null +++ b/frontend/test/frontend_tests/data/workspace_colors_test.cljs @@ -0,0 +1,48 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns frontend-tests.data.workspace-colors-test + (:require + [app.common.uuid :as uuid] + [app.main.data.workspace.colors :as dwc] + [clojure.test :as t] + [potok.v2.core :as ptk])) + +(t/deftest build-change-fill-event + (let [color1 {:color "#fabada" + :opacity 1} + color2 {:color "#fabada" + :opacity 1 + :ref-id uuid/zero + :ref-file uuid/zero} + color3 {:color "#fabada" + :opacity -1} + color4 {:opacity 1 + :color "ffffff"}] + (t/is (ptk/event? (dwc/change-fill #{uuid/zero} color1 1))) + (t/is (ptk/event? (dwc/change-fill #{uuid/zero} color2 1))) + (t/is (thrown? js/Error + (ptk/event? (dwc/change-fill #{uuid/zero} color3 1)))) + (t/is (thrown? js/Error + (ptk/event? (dwc/change-fill #{uuid/zero} color4 1)))))) + +(t/deftest build-add-fill-event + (let [color1 {:color "#fabada" + :opacity 1} + color2 {:color "#fabada" + :opacity 1 + :ref-id uuid/zero + :ref-file uuid/zero} + color3 {:color "#fabada" + :opacity -1} + color4 {:opacity 1 + :color "ffffff"}] + (t/is (ptk/event? (dwc/add-fill #{uuid/zero} color1 1))) + (t/is (ptk/event? (dwc/add-fill #{uuid/zero} color2 1))) + (t/is (thrown? js/Error + (ptk/event? (dwc/add-fill #{uuid/zero} color3 1)))) + (t/is (thrown? js/Error + (ptk/event? (dwc/add-fill #{uuid/zero} color4 1)))))) diff --git a/frontend/test/frontend_tests/runner.cljs b/frontend/test/frontend_tests/runner.cljs index b8bc7c705f..c3def3b7de 100644 --- a/frontend/test/frontend_tests/runner.cljs +++ b/frontend/test/frontend_tests/runner.cljs @@ -2,6 +2,7 @@ (:require [cljs.test :as t] [frontend-tests.basic-shapes-test] + [frontend-tests.data.workspace-colors-test] [frontend-tests.helpers-shapes-test] [frontend-tests.logic.comp-remove-swap-slots-test] [frontend-tests.logic.components-and-tokens] @@ -39,6 +40,7 @@ 'frontend-tests.util-snap-data-test 'frontend-tests.util-simple-math-test 'frontend-tests.basic-shapes-test + 'frontend-tests.data.workspace-colors-test 'frontend-tests.tokens.logic.token-actions-test 'frontend-tests.tokens.logic.token-data-test 'frontend-tests.tokens.import-export-test